Automation QA Testing Course Content

RestAssured with Cucumber BDD Framework

 API is the acronym for Application Programming Interface, which acts as an interface between two applications to communicate with each other irrespective of the programming languages used to develop them. API testing plays a crucial role in the software development process as it helps us to test the business logic of the application even before the UI is ready. There are different types of APIs such as SOAP, REST, and RPC, etc. For now, we will focus on REST API testing using REST Assured.

  1. What is REST ASSURED and How it works

REST stands for REpresentational State Transfer. REST Assured is a java library used for testing and validating the Restful Web Services. It supports Behavior-Driven Development(BDD) syntax like Given, When, and Then notations. It helps us to integrate with testing frameworks like Junit or TestNG.

Let us understand how the Rest Assured Works

  1. Create an HTTP request with all the details
  2. Send the request over the network
  3. Validate the received Response

2. HTTP Request

An HTTP request consists of the following

2.1 URL

The Request URL is the unique address used to make a request. URL consists of the Base URL, Resource, Query, or Path Parameters.

Example: https://reqres.in/api/users/2

Base URL

It is the Base Address for the particular API.

Resource:

A Resource represents the collection that can be accessed from the server.

Path Parameter:

The Path parameter is the variable part of a URL. It is used to point to a particular resource within a collection, such as a user with a specific ID. In Path Parameter we move to the subresource.

Query Parameter:

Query Parameters are optional parameters. It is used to sort/filter the resource. For appending query parameter ‘?’ is added to the end of the URL and implemented as a key-value pair. For Appending multiple query parameters ‘&’ is used in between the key-value pairs.

2.2 HTTP Method/Verb

The four basic Create, Read, Update and Delete (CRUD) operations are performed using the POST, GET, PUT and DELETE methods in the REST interface

POST: This Verb is used to create a new resource on a server.

GET: This Verb is used to get or read data from a server.

PUT or PATCH: Both PUT and PATCH Verbs are used to update a resource on a server. The PUT method is used to update the record entirely. The PATCH method is used to update the record partially instead of updating the entire resource.

DELETE: This Verb is used to delete a resource from a server.

2.3 Headers

Headers represent the meta-data associated with HTTP requests or responses. It is the additional information that is passed between client and server along with the request or response. Headers are used for several purposes, such as authentication, caching, messaging body information, handling cookies, etc. Headers will be key-value pairs or can be a key with multiple values.

2.4 Payload/Body

The Payload/Body contains the information that the user wants to send to the server. The payload is used only with the requests that alter the existing resource or create new ones.

3. HTTP Response

The HTTP Response consists of the status code, Headers and Response body

As we already discussed Headers and Body we will focus on Status Codes

3.1 Status Codes

HTTP status codes help us to understand the status of the response quickly.

100–199: Informational: The request received and process continuing

200–299: Success: The request succeeded

300–399: Redirection: The request is redirecting to another URL

400–499: Client Error: An error occurred from client-side

500–599: Server Error: An error occurred from the server-side

4. Creating a REST Assured Project

  1. Create a Maven Project in the Eclipse/IntelliJ

File->New-> Project -> Maven -> Maven Project -> Create a simple Project -> Next -> Enter Group id ->Artifact id-> Finish

2. In pom.xml add the maven-compiler-plugin and maven-surefire-plugin 
===============================================

Update your pom.xml with below dependencies and build information

================================================================

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>RestAssuredAPIAutomationMay62022</groupId>

  <artifactId>RestAssuredAPIAutomationMay62022</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>


<build>

<plugins>


<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.8.1</version>

<configuration>

<source>1.8</source>

<target>1.8</target>

</configuration>

</plugin>


<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>2.19.1</version>

</plugin>


<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-source-plugin</artifactId>

<executions>

<execution>

<id>attach-sources</id>

<goals>

<goal>jar</goal>

</goals>

</execution>

</executions>

</plugin>


</plugins>

</build>

  <dependencies>

  <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->

<dependency>

    <groupId>io.rest-assured</groupId>

    <artifactId>rest-assured</artifactId>

    <version>5.0.1</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/io.rest-assured/json-path -->

<dependency>

    <groupId>io.rest-assured</groupId>

    <artifactId>json-path</artifactId>

    <version>5.0.1</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/io.rest-assured/json-schema-validator -->

<dependency>

    <groupId>io.rest-assured</groupId>

    <artifactId>json-schema-validator</artifactId>

    <version>5.0.1</version>

</dependency>

  <!-- https://mvnrepository.com/artifact/io.rest-assured/xml-path -->

<dependency>

    <groupId>io.rest-assured</groupId>

    <artifactId>xml-path</artifactId>

    <version>5.0.1</version>

</dependency>


 <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->

<dependency>

    <groupId>org.junit.jupiter</groupId>

    <artifactId>junit-jupiter-api</artifactId>

    <version>5.7.2</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/org.hamcrest/java-hamcrest -->

<dependency>

    <groupId>org.hamcrest</groupId>

    <artifactId>java-hamcrest</artifactId>

    <version>2.0.0.0</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all -->

<dependency>

    <groupId>org.hamcrest</groupId>

    <artifactId>hamcrest-all</artifactId>

    <version>1.3</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/org.json/json -->

<dependency>

    <groupId>org.json</groupId>

    <artifactId>json</artifactId>

    <version>20220320</version>

</dependency>

  

  <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java -->

<dependency>

    <groupId>io.cucumber</groupId>

    <artifactId>cucumber-java</artifactId>

    <version>7.3.4</version>

</dependency>

  <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-junit -->

<dependency>

    <groupId>io.cucumber</groupId>

    <artifactId>cucumber-junit</artifactId>

    <version>7.3.4</version>

    <scope>test</scope>

</dependency>

  <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-core -->

<dependency>

    <groupId>io.cucumber</groupId>

    <artifactId>cucumber-core</artifactId>

    <version>7.3.4</version>

</dependency>

  <!-- https://mvnrepository.com/artifact/net.masterthought/cucumber-reporting -->

<dependency>

    <groupId>net.masterthought</groupId>

    <artifactId>cucumber-reporting</artifactId>

    <version>5.7.0</version>

</dependency>

   </dependencies>

  

</project>

===========================================================

4.1 Automate HTTP Request

We know that REST Assured supports BDD format i.e given, when and then statements

  1. given() — We provide all the input details here i.e. Base URI, Headers, Path Parameter, Query Parameter, and Request Body/Payload.
  2. when() — We specify the Resource, HTTP Request method like POST, GET, PUT, PATCH, or DELETE.
  3. then() — We validate the response i.e the response code, response time, response message, response headers, response body, etc.


Create a folder structure like below screen

under src/test/main

1)com.qa.api.rest.base

  create TestBase.java class

2)com.qa.api.rest.config

create config.properties file

3)create Features folder

4)create step_def package

5)create testRunner package


Create Step_def file for above feature steps


package step_def;


import java.util.List;


import org.junit.jupiter.api.Assertions;

import com.qa.api.rest.base.TestBase;


import io.cucumber.datatable.DataTable;

import io.cucumber.java.en.Given;

import io.cucumber.java.en.Then;

import io.cucumber.java.en.When;

import io.restassured.RestAssured;

import io.restassured.response.Response;


public class GetAPITest extends TestBase{


Response resp;

@Given("^provide valid endpoint to fetch all users$")

public void provide_valid_endpoint_to_fetch_all_users() throws Throwable {

   //setting the base Url

RestAssured.baseURI=readPropertyValue("baseUrl");

   //setting the endpoint url

RestAssured.basePath=readPropertyValue("getAllUserEndPoint");

}


@When("^the request is send to the server$")

public void the_request_is_send_to_the_server() throws Throwable {

   resp=RestAssured.given().header("Accept","application/json").

   header("Content-type", "application/json").

   queryParam("page", 2).

   when().

   get().

   then().

   contentType("application/json").

   extract().response();

}


@Then("^validate the response statuscode 200$")

public void validate_the_response_statuscode_200() throws Throwable {

   int respCode=resp.getStatusCode();

   Assertions.assertEquals(respCode, 200);

}


@When("^the request is send to the server with page number as \"([^\"]*)\"$")

public void the_request_is_send_to_the_server_with_page_number_as_something(int pageNumber) throws Throwable {

resp=RestAssured.given().header("Accept","application/json").

   header("Content-type", "application/json").

   queryParam("page", pageNumber).

   when().

   get().

   then().

   contentType("application/json").

   extract().response();

}


@Then("^validate the response of first user record having email as \"([^\"]*)\"$")

public void validate_the_response_of_first_user_record_having_email_as_something(String emailid) throws Throwable {

   //extracting the response body field value

String email=resp.path("data[0].email");

Assertions.assertEquals(email, emailid);

}


@Then("^validate response statuscode (.+)$")

public void validate_response_statuscode(int respstatuscode) throws Throwable {

int respCode=resp.getStatusCode();

Assertions.assertEquals(respCode, respstatuscode); 

}


@Given("^provide valid endpoint to fetch the single user$")

public void provide_valid_endpoint_to_fetch_the_single_user() throws Throwable {

   //set the base url

RestAssured.baseURI=readPropertyValue("baseUrl");

//set the basepath

RestAssured.basePath=readPropertyValue("getSingleUserEndPoint");

}


@When("^the request is send to the server to fetch single user$")

public void the_request_is_send_to_the_server_to_fetch_single_user() throws Throwable {

  resp=RestAssured.given().header("Accept","application/json").

   header("Content-type", "application/json").

   when().

   get("/2").

   then().

   contentType("application/json").

   extract().response();

}


@Then("^validate the response body fields$")

public void validate_the_response_body_fields(DataTable values) throws Throwable {

   List<List<String>>ls=values.asLists();

int id=resp.path("data.id");

   System.out.println("id value is:"+id);

   Assertions.assertEquals(Integer.parseInt(ls.get(0).get(0)), id);

   //fetch the email

   String emailVal=resp.path("data.email");

   System.out.println("email value is:"+emailVal);

   Assertions.assertEquals(ls.get(0).get(1), emailVal);

 //fetch the first name

   String firstNameVal=resp.path("data.first_name");

   System.out.println("firstName value is:"+firstNameVal);

   Assertions.assertEquals(ls.get(0).get(2), firstNameVal);

   

 //fetch the lastname

   String lastnameVal=resp.path("data.last_name");

   System.out.println("lastname value is:"+lastnameVal);

   Assertions.assertEquals(ls.get(0).get(3), lastnameVal);

}


@Given("^provide valid endpoint to fetch the single userNotFound$")

public void provide_valid_endpoint_to_fetch_the_single_usernotfound() throws Throwable {

//set the base url

RestAssured.baseURI=readPropertyValue("baseUrl");

//set the basepath

RestAssured.basePath=readPropertyValue("getSingleUserNotFoundEndPoint");

}


@When("^the request is send to the server to fetch single user not found$")

public void the_request_is_send_to_the_server_to_fetch_single_user_not_found() throws Throwable {

resp=RestAssured.given().header("Accept","application/json").

   header("Content-type", "application/json").

   when().

   get().

   then().

   contentType("application/json").

   extract().response();  

}


@Then("^validate the response statuscode$")

public void validate_the_response_statuscode(DataTable exrespcode) throws Throwable {

  int respCode=resp.getStatusCode();

 List<String>ls=exrespcode.asList();

 int expval=Integer.parseInt(ls.get(0));

Assertions.assertEquals(respCode,expval); 

}


}


=========================================

Create a Runner file

============================================

package testRunner;


import org.junit.runner.RunWith;


import io.cucumber.junit.Cucumber;

import io.cucumber.junit.CucumberOptions;


@RunWith(Cucumber.class)


@CucumberOptions(

    features = "D:\\eclipseworkspaceAug2018\\RestAssuredAPIAutomationMay62022\\src\\test\\java\\Features",

    glue = {"step_def"},

    plugin={"pretty","html:target/report.html", "json:json_output/cucumber.json", "junit:junit_xml/cucumber.xml"},

    dryRun=false, //mapping between feature & stepdefinition is proper or not

    monochrome=true,//display the console output in a proper readable format

    publish = true,

    stepNotifications=true

    //tags = "@smoke"

    )

public class TestRunner {

   

}

=================================================================
Feature 2:
Feature: REQRES POST API Feature

  Scenario: ReqRes POST API to create user
    Given provide valid endpoint to create user
    When the request is send to the server with requestbody
    Then validate create user response statuscode
      | 201 |
    And validate the responsebody fields

  Scenario Outline: ReqRes POST API to create users
    Given provide valid endpoint to create users
    When the request is send to the server with requestbody as "<name>" and "<job>"
    Then validate create user response statuscode
      | 201 |
    And validate the responsebody fields

    Examples: 
      | name      | job                  |
      | Morpheus  | leader               |
      | Ramesh Ch | Automation Test lead |
==========================================================
StepDef file
package step_def;
import org.json.JSONObject;
import org.junit.jupiter.api.Assertions;

import com.qa.api.rest.base.TestBase;

import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.restassured.RestAssured;
import io.restassured.response.Response;

public class PostAPITest extends TestBase{

Response resp;
JSONObject jsonObj=new JSONObject();
@Given("^provide valid endpoint to create user$")
public void provide_valid_endpoint_to_create_user() throws Throwable {
    //set the baseUrl
RestAssured.baseURI=readPropertyValue("baseUrl");
//set the base path
RestAssured.basePath=readPropertyValue("getAllUserEndPoint");
}

@When("^the request is send to the server with requestbody$")
public void the_request_is_send_to_the_server_with_requestbody() throws Throwable {
jsonObj.put("name", "CH Ramesh");
jsonObj.put("job", "AutomationTestLead"); 
resp=RestAssured.given().header("Accept", "application/json").
    header("Content-Type","application/json").
    body(jsonObj.toString()).
    when().
    post().
    then().
    extract().response();
     
     
}

@Then("^validate create user response statuscode$")
public void validate_create_user_response_statuscode(DataTable code) throws Throwable {
   int respCode=resp.getStatusCode();
  System.out.println("session id is:"+resp.getSessionId());
  System.out.println("statusline:"+resp.getStatusLine());
  System.out.println("response time:"+resp.getTime());
   Assertions.assertEquals(Integer.parseInt(code.asList().get(0)), respCode);
}

@Then("^validate the responsebody fields$")
public void validate_the_responsebody_fields() throws Throwable {
    String nameval=resp.path("name");
    System.out.println("name value is:"+nameval);
    Assertions.assertEquals(jsonObj.get("name"), nameval);
    String jobval=resp.path("job");
    Assertions.assertEquals(jsonObj.get("job"), jobval);
}
@Given("^provide valid endpoint to create users$")
public void provide_valid_endpoint_to_create_users() throws Throwable {
    //set base Url
RestAssured.baseURI=readPropertyValue("baseUrl");
//set the base path
RestAssured.basePath=readPropertyValue("getAllUserEndPoint");
}
@When("^the request is send to the server with requestbody as \"([^\"]*)\" and \"([^\"]*)\"$")
public void the_request_is_send_to_the_server_with_requestbody_as(String name, String job) throws Throwable {
jsonObj.put("name", name);
jsonObj.put("job", job); 
resp=RestAssured.given().header("Accept", "application/json").
    header("Content-Type","application/json").
    body(jsonObj.toString()).
    when().
    post().
    then().
    extract().response();

}




}
===========================================================
Feature PUT
@putapi
Feature: REQRES PUT API Feature
  Scenario: ReqRes PUT API to update user
    Given provide valid endpoint to update user
    When the request is send to the server with requestbody to update
    Then validate update user response statuscode
      | 200 |
    And validate the update responsebody fields
============================================
Step Defin for Put feature
-------------------------------------------------------------------------------
package step_def;

import java.util.List;

import org.json.JSONObject;
import org.junit.jupiter.api.Assertions;

import com.qa.api.rest.base.TestBase;

import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.restassured.RestAssured;
import io.restassured.response.Response;

public class PutApiTest extends TestBase{

Response resp;
JSONObject jsonObj=new JSONObject();

@Given("^provide valid endpoint to update user$")
public void provide_valid_endpoint_to_update_user() throws Throwable {
//set the baseUrl
RestAssured.baseURI=readPropertyValue("baseUrl");
//set the base path
RestAssured.basePath=readPropertyValue("getAllUserEndPoint");
}

@When("^the request is send to the server with requestbody to update$")
public void the_request_is_send_to_the_server_with_requestbody_to_update() throws Throwable {
jsonObj.put("name", "Muniraja");
jsonObj.put("job", "Automation Architect"); 
resp=RestAssured.given().header("Accept", "application/json").
    header("Content-Type","application/json").
    body(jsonObj.toString()).
    when().
    put("/2").
    then().
    extract().response();
}

@Then("^validate update user response statuscode$")
public void validate_update_user_response_statuscode(DataTable table) throws Throwable {
  int respCode=resp.getStatusCode();
  System.out.println("Update Api Status code is:"+respCode);
  //implement DataTable concept
  List<String>ls=table.asList();
  //convert String object into int
  int expRespCode=Integer.parseInt(ls.get(0));
  Assertions.assertEquals(expRespCode, respCode);
}

@Then("^validate the update responsebody fields$")
public void validate_the_update_responsebody_fields() throws Throwable {
    String respname=resp.path("name");
    System.out.println("resp name is:"+respname);
    Assertions.assertEquals(jsonObj.get("name"), respname);
    String respjob=resp.path("job");
    System.out.println("resp job is:"+respjob);
    Assertions.assertEquals(jsonObj.get("job"), respjob);
    String respupdateAt=resp.path("updatedAt");
    System.out.println("updated at:"+respupdateAt);
    
}
}
==================================================================
Feature Delete API
-------------------
@deleteapi
Feature: REQRES DELETE API Feature
  Scenario: ReqRes DELETE API to delete the specific user
    Given provide valid endpoint to delete the user
    When the request is send to the server delete the user
    Then validate delete user response statuscode
      | 204 |
    
===============================
package step_def;

import java.util.List;

import org.junit.jupiter.api.Assertions;

import com.qa.api.rest.base.TestBase;

import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.restassured.RestAssured;
import io.restassured.response.Response;

public class DeleteApiTest extends TestBase{
Response resp;
@Given("^provide valid endpoint to delete the user$")
public void provide_valid_endpoint_to_delete_the_user() throws Throwable {
    //set base url
RestAssured.baseURI=readPropertyValue("baseUrl");
//set basepath
RestAssured.basePath=readPropertyValue("getSingleUserEndPoint");
}

@When("^the request is send to the server delete the user$")
public void the_request_is_send_to_the_server_delete_the_user() throws Throwable {
   resp=RestAssured.given().header("Accept", "application/json").
    header("Content-Type","application/json").
    when().
    delete("/2").then().extract().response();
}

@Then("^validate delete user response statuscode$")
public void validate_delete_user_response_statuscode(DataTable table) throws Throwable {
  int respCode=resp.getStatusCode();
  System.out.println("Update Api Status code is:"+respCode);
  //implement DataTable concept
  List<String>ls=table.asList();
  //convert String object into int
  int expRespCode=Integer.parseInt(ls.get(0));
  Assertions.assertEquals(expRespCode, respCode);
}

}
===================================================================