Overview

Skill Level: Any Skill Level

This article will depict how a Java based framework can be build using BDD approach through Cucumber in conjunction with Rest-Assured java based library.

Ingredients

REST APIs are mainly responsible for running most of the applications these days. Therefore, it is important to ensure that these API services are running as expected by validating the responses. Behavioral Data Driven(BDD) framework can be build up to monitor the smooth run of APIs through an automated way. It will be a reusable asset for REST API testing which can be further integrated with Jenkins to achieve Continuous Integration.

This article will depict how a Java based framework can be build using BDD approach through Cucumber in conjunction with Rest-Assured java based library.

Rest-Assured is a Java based DSL (Domain Specific Language) which supports multiple HTTP request. These multiple requests include GET, POST, PUT, DELETE, PATCH, OPTIONS and HEAD methods. It also allows requests to be constructed with multiple parameters, headers, and their respective body.

 In this article I will cover the validation of response status code, header parameter, presence of mandatory tag, validation of field value and content-type of response for GET and POST HTTP request using JSON based requests and responses. It will allow multiple data to run for the single request and structured report will be generated in HTML format using Extent Report functionality.

Following diagram demonstrates the complete flow of the framework and Continuous Integration.

Framework

PRE-REQUISITES :

1)      Maven-Cucumber Framework

2)      Rest Assured

3)      Extent Reporting

4)      JXL jar configuration to perform Excel Read/Write Operations

Step-by-step

  1. Example of GET and POST requests

     

     

    For example: Let’s assume a scenario of GET request API getClientDetails which accepts client Id as Input in query parameter and provides all the details of that client in the response as below.

    getClientDetails Response:

    {

    "clientDetails":

            {

                "name": "Mark",

                "address": "45-Avenue",

                "accountId": "6755JJJJ",

                "birthDate": "2017-11-16",

                "clientId": "CUSTID"

    }

    }

    And assume following as the request body for the POST request createClient and it returns clientId in response as below.

    createClient Request Body  :                        

    {

    "clientDetails":

            {

                "name": "Mark",

                "address": "45-Avenue",

                "accountId": "6755JJJJ",

                "birthDate": "2017-11-16",

    }

    }

    createClient Response :

    {

    “clientInfo”:

    {

                "clientId": "CUSTID"

    }

    }
  2. Step 1- Building Excel

    The excel will have all the required input parameters which are needed to run the GET and POST request.

    Assuming above scenario for GET and POST request, I have designed an excel format which will have all the required inputs for both the requests. In case of multiple test data run, data will be passed in multiple worksheets.

    A)      Input for GET Request getClientDetails:

    getCE

    Any number of Query parameters can be passed through the excel depending upon the type of API. Name and value of query parameter can be passed through the respective columns, which are column C and Column D of the excel.

    In case of additional test required for another GET API where different set of query parameter and base URI is required, then same can be designed in a different worksheet of the same excel. To check for more mandatory tags, name of mandatory tags can be added in column G.

    B)      Input for POST Request for createClient:

    JSON request body for the POST request will be passed through *.json file and the name of the file will be provided as input in excel.

    PstCE

    In case of additional test required for another is required with different JSON request body and base URI is required, then same can be designed in different worksheet of the same excel. To check for more mandatory tags, name of mandatory tags can be added in column G.

  3. Step 2 – Building Cucumber Feature File for GET and POST Operations

    A)      Considering the GET request for getClientDetails following feature file will be created

    Feature: This feature is to check GET API

     

      Scenario Outline: Check if user is able to submit GET API request

       Given I want to execute service <serviceName>

        When I submit the GET request as per the data in Excel Worksheet <EWorksheet>

        And I validate status code

        And I validate mandatory tag in response from Excel Worksheet <EWorksheet>

        And I validate response content

        And I validate tag values in response from Excel Worksheet <EWorksheet>

        And I validate header parameter in response

    Examples:

    | serviceName          | EWorksheet |

    | getClientDetails      |  0         |

    | getClientDetails      |  1         |

     

    Here getClientDetails will be submitted twice as two rows has been passed in examples section and the details will be passed from excel worksheet sheet1 and second run will fetch the details which are being passed in excel worksheet sheet2.

    EWorksheet column specifies the excel worksheet number for the respective data being passed to the request.

    B)      Considering the POST request for createCard following feature file will be created

    Feature: This feature is to check POST API

     

      Scenario Outline: Check if user is able to submit POST service

       Given I want to execute service <serviceName>

        When I the POST request as per the data in Excel Worksheet <EWorksheet>

        And I validate status code

        And I validate mandatory tag in response from Excel Worksheet <EWorksheet>

        And I validate response content

        And I validate header parameter in response

    Examples:

    | serviceName         | EWorksheet |

    | createClient          |  2         |

    | createClient          |  3         |

     

    In this scenario like GET request, createClient will also be submitted twice due to two rows been provided in Examples section and EWorksheet column specifies the excel worksheet number for the respective data being passed to the request.

    As it can be seen that, five scenario steps for GET and POST request verification are identical, functions will be reused.

  4. Step 3 – Writing Step Definition File

    Following is the code snippet of the step definition file

    /*Code Goes Here*/
    package cucumber.examples.java.APITest.stepDefinitions; 

    import cucumber.api.java.en.Given;

    import cucumber.api.java.en.Then;

    import cucumber.api.java.en.When;

    import cucumber.examples.java.testNG.DriverManager;

    import org.apache.log4j.Logger;

    import static org.testng.Assert.assertEquals;

    import java.io.File;

    import ExcelOperations.BaseExcel;

    import io.restassured.RestAssured;

    import io.restassured.response.Response;

    import io.restassured.response.ResponseBody;

    import io.restassured.response.ValidaworksheetleResponse;

    import io.restassured.specification.RequestSpecification; 

    public class APITesting { 

        static Logger log = Logger.getLogger(APITesting.class);

        public BaseExcel excel= new BaseExcel(); //To create an object of BaseExcel Class

        public String[][] requestData; //This is the 2D string array which will contain all the data
    from Input excel for a particular worksheet

                Response response=null;

                  ValidaworksheetleResponse json;

                  RequestSpecification request;  

       String filepath= "The Path of the input excel to be provided";  
     

        @Given("^I want to execute service (.+)$")

        public void givenIwantToexecuteSercive(String service) {

            log.info("We are going to execute service"+service);      

        } 

       @When("^I submit the GET request as per the data in Excel Worksheet (.+)$")

        public void whenIsubmitgetrequest(String st2) throws IOException {
                 

                     int no=Integer.parseInt(st2); //Converting the value of Excel worksheet to Integer

                     requestData=excel.readExcel(filepath, no); //Capturing the input data from excel to 2D string array

                      String baseURI=requestData[1][1]; //Capturing the value of baseURI from excel into variable

                     int count=requestData.length; //Initialising the variable with array length

                     String [] Qparam=new String[count];

                     String [] Qvalue=new String[count];

                     String SERVICE_ENDPOINT = null;

                     int chk=0;

     //Following loop will capture all the Query parameter name
    and value in Qparam and Qvalue array respectively.
    for (int i=1;i<count;i++)

    {

      if(!(requestData[i][2].isEmpty()))

      {

      Qparam[i]=requestData[i][2];

      Qvalue[i]=requestData[i][3];

      chk++;

    }                                         

      }

    //Following if condition and for loop build the resulting API URI based on
    the query parameters received from the input excel.

    SERVICE_ENDPOINT =baseURI;

             String Query=null;

             if(chk==1)

             {

             SERVICE_ENDPOINT = baseURI+"?"+requestData[1][2]+"="+requestData[1][3];

             }

             if(chk>1)

             {

      SERVICE_ENDPOINT = baseURI+"?"+requestData[1][2]+"="+requestData[1][3];
      for(int i=1;i<chk;i++)

        {
      Query = Query.concat("&"+requestData[i+1][2]+"="+requestData[i+1][3]);

      SERVICE_ENDPOINT = SERVICE_ENDPOINT.concat(Query);

        }

      }               

                      request = RestAssured.given();

                      request.header("header1","User1"); //Passed the value of header parameter

                      request.header("header2","User2");//Passed the value of header parameter

                      response = request.when().get(SERVICE_ENDPOINT);//Submit the request

                                

    ResponseBody body = response.getBody();                           

          excel.writeExcel(filepath, no, 10, 1, response.prettyPrint());//Print the service response in excel
                  

        }


                  @SuppressWarnings("deprecation")

                  @When("^I validate status code$") 

        public void whenIvalidateStatusCode() throws IOException {

                  String status=requestData[1][5];
    //Capture the expected value of status code passed in input excel

                  int statusCode = response.getStatusCode();
    //Capture the resulting status code after submitting the request

                  int code=Integer.parseInt(status);

                  Assert.assertEquals(code, statusCode);
                     

         }

        @When("^I validate mandatory tag in response from Excel Worksheet (.+)$")

        public void validateMandatoryTag(String st2) {

                  int no=Integer.parseInt(st2);

            int rowcount=requestData.length;

            ResponseBody body = response.getBody();

            String bodyAsString = body.asString();

            for(int i=1;i<rowcount;i++)

            {

    String Mandatoryfield=requestData[i][6];//Capture the mandatory tag names from input excel
    Boolean value=bodyAsString.contains(Mandatoryfield);
    //To verify if mandatory tag is present in response.
    if(value)
       {
            excel.writeExcel(filepath, no, 7, i, "Mandatory Tag Present");
    //This will write the result in excel.

        }
    else

        {

         excel.writeExcel(filepath, no, 7, i, "Mandatory Tag Not Present");
    //This will write the result in excel.

    }

            }

        }  

        @When("^I validate response content$")

        public void i_validate_response_content() throws InterruptedException{

                  String contentType = response.header("Content-Type");

                  assertEquals(contentType, "application/json; charset=utf-8");
    //To verify if the response is coming in valid JSON format

        } 

        @When("^I validate tag values in response from Excel Worksheet (.+)$")

        public void i_validate_tag_values_in_response(String st2) throws InterruptedException{

        int no=Integer.parseInt(st2);

            int rowcount=requestData.length;

            for(int i=1;i<rowcount;i++)

            {

                  String tagname=requestData[i][6];

            String val=response.path(requestData[1][4]+"."+tagname);
    //To capture the value of the tags provided in input excel

            String Exval=requestData[i][8];

    if(val.equals(Exval))

     {

    excel.writeExcel(filepath, no, 9, i, "Tag Value Matched");
    //This will write the result in excel.

    }
    else

    {
       excel.writeExcel(filepath, no, 9, i, "Tag Value Does Not Matched,Value obtained is "+val);
    //This will write the result in excel.

    }

    }
            

        }

        @When("^I validate header parameter in response$")

        public void I_validate_header_parameter_in_response() throws InterruptedException, FindFailed{

                  String journeyId = response.header("header1");

                  assertEquals(header1, "User1");//To validate the value of header in response.

        } 

        @When("^I the POST request as per the data in Excel Worksheet (.+)$")

        public void I_submit_POST_request(String st2) throws InterruptedException, IOException{             

                     int no=Integer.parseInt(st2);

                     requestData=excel.readExcel(filepath, no);

                     String FileName=requestData[1][1];//To capture the value of Json file name in variable

                     String baseURI=requestData[1][2];//To capture the value of baseURI in variable    

                  File file = new File("To provide the path of JSON file"+FileName);

                  response=RestAssured.given().header("header1", "User1").header("header2", "User2").body(file).with().
    contentType("application/json").then().expect().

                    statusCode(200).

                    when().post(baseURI);//Invoke the POST request

            String bodyAsString = response.asString();

            excel.writeExcel(filepath, no, 8, 1, bodyAsString);//To print the response in excel 

        }
    }
  5. Step 4- Execution of framework

    The framework can be executed by using cucumber runner file.

  6. Step 5 – Extent Report and Excel Result

    Once the framework is executed we will have our results both in excel and extent report. Following is the excel result for GET and POST request.

    1)      Result of getClientDetails

    GR

    2)      Result of createClient

    PR

    And Extent Report will look as below.

    E1

    In case a test case of status code 200 fails, the code will skip the following steps for that scenario and it will mark the scenario as Fail.

    The extent report will look as below in case of failure scenario.

    E2

     

  7. Step 6 – Jenkins Integration

    The framework can be easily integrated with Jenkins due to its java based nature. The extent report which gets generated can be added to the ‘Post build step’ of Jenkins and same can be sent to various stakeholders via email.

  8. ADVANTAGES OF FRAMEWORK:

    1)Reusability: The framework can be reused to test any GET and POST REST API request. It can be enhanced further to include other HTTP request type as PATCH, DELETE etc.

    2)High Volume Data Testing: The framework makes use of test data provided in excel. The excel can be utilized to execute different types of test cases using various type of test data.

    3)Easy to Use-One-Click: As the framework can be triggered on single click, it makes it easy for anyone to execute the test and study the response through reports.

    4)Continuous Integration with Jenkins: As the framework is Java based it is easy to integrate it with Jenkins and achieve continuous integration.

    5)Structured HTML Reporting: As we get result in form of HTML report in email. It is convenient to capture the use cases and their results in consolidated format within single HTML file which can be easily shared and is easy to read.

    6) Ability to Write Clean Code: Given-when-then style helps in specifying pre-conditions under the Given section, behavior under test under the When section, and verifications under the Then section. This helps in maintaining a clear separation of concerns within a test, thus leading to a very readable test.

Join The Discussion