How to handle token expiration and automatic refreshing of tokens in REST Assured?

HOME

<dependencies>
 
       <!-- Rest Assured Dependency -->
      <dependency>
         <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
      </dependency>

      <!-- JSON path Dependency -->
      <dependency>
         <groupId>io.rest-assured</groupId>
         <artifactId>json-path</artifactId>
         <version>5.4.0</version>
         <scope>test</scope>
      </dependency>
 
        <!-- TestNG Dependency-->
      <dependency>
          <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>7.8.0</version>
         <scope>test</scope>
       </dependency>
 
</dependencies>

import io.restassured.RestAssured;
import io.restassured.response.Response;

import java.time.Instant;

public class TokenGeneration {

    private static String accessToken;
    private static Instant tokenExpiryTime;
    Response response;
    int expiresIn;

    // Method to obtain initial token
    public static String getAccessToken() {
        if (accessToken == null || isTokenExpired()) {
            refreshAccessToken();
        }
        return accessToken;
    }

    // Method to check if the token is expired
    private static boolean isTokenExpired() {
        return tokenExpiryTime == null || Instant.now().isAfter(tokenExpiryTime);
    }

    // Method to refresh token
    private static void refreshAccessToken() {
            response = RestAssured.given()
            .contentType("application/x-www-form-urlencoded")
            .formParam("grant_type", "client_credentials")
            .formParam("client_id", "your-client-id")
            .formParam("client_secret", "your-client-secret")
            .post("https://your-auth-server.com/oauth/token");

        accessToken = response.jsonPath().getString("access_token");
        expiresIn = response.jsonPath().getInt("expires_in");
        tokenExpiryTime = Instant.now().plusSeconds(expiresIn);

        System.out.println("Access Token: " + accessToken);
        System.out.println("Token Expiry Time: " + tokenExpiryTime);
    }
}

tokenExpiryTime == null || Instant.now().isAfter(tokenExpiryTime);
tokenExpiryTime = Instant.now().plusSeconds(expiresIn);
import static io.restassured.RestAssured.given;
import org.testng.annotations.Test;

public class ApiTest {

        String token = TokenGeneration.getAccessToken();
        Response response;

       @Test
       public getResponse() {
         response = given()
                .auth().oauth2(token)
                .when()
                .get("https://example.com/protected/resource")
                .then()
                .statusCode(200)
                .extract().response();

        System.out.println("Response: " + response.asString());
    }
}

private static final long TOKEN_EXPIRY_BUFFER_SECONDS = 60;  // 1 minute buffer
    
private static boolean isTokenExpired() {
        return tokenExpiryTime == null || Instant.now().isAfter(tokenExpiryTime.minusSeconds(TOKEN_EXPIRY_BUFFER_SECONDS));
 }

How to compare JSON File with JSON Response

HOME

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.4.0</version>
      <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.3</version>
    </dependency>
</dependencies>

package com.example;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class JsonFileComparison {

    @Test
    public void compareResponse() throws IOException {

        // Path to the JSON file
        File jsonFile = new File("src/test/resources/expectedUser.json");

        // Read JSON content from file
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonFromFile = objectMapper.readTree(jsonFile);

        // Make an API call
        Response response = RestAssured.given().when().get("https://reqres.in/api/users/3").then().extract().response();
        String expectedResponse = response.getBody().asString();
        System.out.println("Response is : " + expectedResponse);

        // Verify the status code
        response.then().statusCode(200);

        // Read JSON content from response
        JsonNode jsonFromResponse = objectMapper.readTree(expectedResponse);

        Assert.assertEquals(jsonFromFile, jsonFromResponse);

        // Compare JSON content
        if (jsonFromFile.equals(jsonFromResponse)) {
            System.out.println("JSON from file matches JSON from response");
        } else {
            System.out.println("JSON content does not match");
        }
    }
}

ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonFromFile = objectMapper.readTree(jsonFile);

Response response = RestAssured.given().when().get("https://reqres.in/api/users/3").then().extract().response();
String expectedResponse = response.getBody().asString();
System.out.println("Response is : " + expectedResponse);

// Verify the status code
response.then().statusCode(200);

JsonNode jsonFromResponse = objectMapper.readTree(expectedResponse);
 Assert.assertEquals(jsonFromFile, jsonFromResponse);

REST Assured: Validating HTTP Response Status Code, Line, Body, Headers, Content Type

HOME

 <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>5.5.0</version>
            <scope>test</scope>
</dependency>

@Test
    public void verifyStatusCode() {

        String BaseURL = "https://dummy.restapiexample.com/api";

        // GIVEN
       Response response =  given()

                // WHEN
                .when()
                .get("https://reqres.in/api/users/2")

                // THEN
                .then()
               .extract().response();

       int actualStatusCode = response.getStatusCode();
       System.out.println("Status Code : " + actualStatusCode);

        Assert.assertEquals(200, actualStatusCode);

    }

 @Test
    public void verifyStatusLine() {

        // GIVEN
        Response response =  given()

                // WHEN
                .when()
                .get("https://reqres.in/api/users/2")

                // THEN
                .then()
                .extract().response();

        String actualStatusLine = response.getStatusLine();
        System.out.println("Status Line : " + actualStatusLine);

        Assert.assertEquals("HTTP/1.1 200 OK", actualStatusLine);

    }

  @Test
    public void verifyResponseBody() {

        // GIVEN
        Response response =  given()

                // WHEN
                .when()
                .get("https://reqres.in/api/users/2")

                // THEN
                .then()
                .extract().response();

        String actualResponseBody = response.getBody().asString();
        System.out.println("Response Body : " + actualResponseBody);

        JsonPath jsonPath = response.jsonPath();
        String actualResponse_Id = jsonPath.getString("data.id");
        System.out.println("Response Id : " + actualResponse_Id);

        Assert.assertEquals("2", actualResponse_Id);

    }

@Test
    public void verifyResponseHeader() {

        // GIVEN
        Response response =  given()

                // WHEN
                .when()
                .get("https://reqres.in/api/users/2")

                // THEN
                .then()
                .extract().response();

        Headers allHeaders = response.getHeaders();
        System.out.println("All Headers : " + allHeaders);

       for(Header header: allHeaders){
           System.out.println(header.getName() +  ":" + header.getValue());
       }

       Assert.assertTrue(allHeaders.getValue("Content-Encoding").contains("gzip"));

    }

 @Test
    public void verifyContentType() {

        // GIVEN
        Response response =  given()

                // WHEN
                .when()
                .get("https://reqres.in/api/users/2")

                // THEN
                .then()
                .extract().response();

        String actualContentType = response.getContentType();
        System.out.println("Actual ContentType : " + actualContentType);

         Assert.assertEquals("application/json; charset=utf-8", actualContentType);

    }

XmlPath in Rest Assured

HOME

 <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>xml-path</artifactId>
            <version>5.5.0</version>
 </dependency>

<shopping>
 <category type="groceries">
 <item>
 <name>Chocolate</name>
 <price>10</price>
 </item>
 <item>
 <name>Coffee</name>
 <price>20</price>
 </item>
 </category>
 <category type="supplies">
 <item>
 <name>Paper</name>
 <price>5</price>
 </item>
 <item quantity="4">
 <name>Pens</name>
 <price>15</price>
 </item>
 </category>
 <category type="present">
 <item when="Aug 10">
 <name>Kathryn's Birthday</name>
 <price>200</price>
 </item>
 </category>
 </shopping>

import io.restassured.path.xml.XmlPath;
import io.restassured.path.xml.element.Node;
import org.junit.Test;

import java.util.List;


public class XMLPath_Demo {

    String body = "<shopping>\n" +
            " <category type=\"groceries\">\n" +
            " <item>\n" +
            " <name>Chocolate</name>\n" +
            " <price>10</price>\n" +
            " </item>\n" +
            " <item>\n" +
            " <name>Coffee</name>\n" +
            " <price>20</price>\n" +
            " </item>\n" +
            " </category>\n" +
            " <category type=\"supplies\">\n" +
            " <item>\n" +
            " <name>Paper</name>\n" +
            " <price>5</price>\n" +
            " </item>\n" +
            " <item quantity=\"4\">\n" +
            " <name>Pens</name>\n" +
            " <price>15</price>\n" +
            " </item>\n" +
            " </category>\n" +
            " <category type=\"present\">\n" +
            " <item when=\"Aug 10\">\n" +
            " <name>Kathryn's Birthday</name>\n" +
            " <price>200</price>\n" +
            " </item>\n" +
            " </category>\n" +
            " </shopping>";

    @Test
    public void test() {
        XmlPath xmlPath = new XmlPath(body);

        //Get the name of the first category item:
        String name = xmlPath.get("shopping.category.item[0].name");
        System.out.println("Item Name: " + name);

        // Get the price of the first category price:
        String chocolatePrice = xmlPath.get("shopping.category.item[0].price");
        System.out.println("chocolatePrice :" + chocolatePrice);

        // Get the price of the second category price:
        String coffeePrice = xmlPath.get("shopping.category.item[1].price");
        System.out.println("coffeePrice :" + coffeePrice);

        //To get the number of category items:
        int itemSize = xmlPath.get("shopping.category.item.size()");
        System.out.println("Item Size: " + itemSize);

       // Get a specific category:
        Node category = xmlPath.get("shopping.category[0]");
        System.out.println("category :" + category);
        
        //To get the number of categories with type attribute equal to 'groceries':
        int groceryCount = xmlPath.get("shopping.category.findAll { it.@type == 'groceries' }.size()");
        System.out.println("groceryCount :" + groceryCount);

        //Get all items with price greater than or equal to 10 and less than or equal to 20:
        List<Node> itemsBetweenTenAndTwenty = xmlPath.get("shopping.category.item.findAll { item -> def price = item.price.toFloat(); price >= 10 && price <= 20 }");
        System.out.println("itemsBetweenTenAndTwenty :" + itemsBetweenTenAndTwenty);

       // Get the chocolate price:
        int priceOfChocolate = xmlPath.getInt("**.find { it.name == 'Chocolate' }.price");
        System.out.println("priceOfChocolate :" + priceOfChocolate);
    }
}

Parameterizing REST Assured Tests with junit4-dataprovider Dependency

HOME

<!-- Data Provider -->
 <dependency>
      <groupId>com.tngtech.junit.dataprovider</groupId>
      <artifactId>junit4-dataprovider</artifactId>
      <version>${junit.dataprovider.version}</version>
      <scope>test</scope>
</dependency>

<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>com.example</groupId>
  <artifactId>Parameterized_APITests</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Parameterized_APITests</name>
  <url>http://maven.apache.org</url>

  <properties>
    <rest-assured.version>5.4.0</rest-assured.version>
    <junit.version>4.13.2</junit.version>
    <junit.dataprovider.version>2.10</junit.dataprovider.version>
    <maven.compiler.plugin.version>3.12.1</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.2.3</maven.surefire.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>
    <!-- Rest-Assured Dependency -->
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>${rest-assured.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- JUnit4 Dependency -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Data Provider -->
    <dependency>
      <groupId>com.tngtech.junit.dataprovider</groupId>
      <artifactId>junit4-dataprovider</artifactId>
      <version>${junit.dataprovider.version}</version>
      <scope>test</scope>
    </dependency>
    
  </dependencies>

  <build>

    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.plugin.version}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>
        <configuration>
          <testFailureIgnore>true</testFailureIgnore>
        </configuration>
      </plugin>

    </plugins>
  </build>
</project>

@RunWith(DataProviderRunner.class)

 @DataProvider
    public static Object[][] responseData() {
        return new Object[][] {
                { "1", "George", "Bluth" },
                { "2", "Janet", "Weaver" },
                { "3", "Emma", "Wong" },
                { "4", "Eve", "Holt" }
        };
    }

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.junit.Test;
import org.junit.runner.RunWith;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;

@RunWith(DataProviderRunner.class)
public class ParameterizedTets {

    @DataProvider
    public static Object[][] responseData() {
        return new Object[][] {
                { "1", "George", "Bluth" },
                { "2", "Janet", "Weaver" },
                { "3", "Emma", "Wong" },
                { "4", "Eve", "Holt" }
        };
    }

    @Test
    @UseDataProvider("responseData")
    public void verifyResponse(String id, String expectedFirstName, String expectedLastName)
    {
        given().
                when().
                pathParam("id", id).
                get("https://reqres.in/api/users/{id}").
                then().
                assertThat().
                statusCode(200).
                body("data.first_name", equalTo(expectedFirstName)).
                body("data.last_name", equalTo(expectedLastName));
    }
}

How to handle async requests in API Testing

HOME

<dependency>
            <groupId>org.asynchttpclient</groupId>
            <artifactId>async-http-client</artifactId>
            <version>3.0.0.Beta3</version>
</dependency>

package org.example;

import com.jayway.jsonpath.JsonPath;
import org.asynchttpclient.Dsl;
import org.asynchttpclient.Response;
import org.junit.Assert;
import org.junit.Test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import static org.hamcrest.MatcherAssert.assertThat;


public class AsyncRequest_Demo {

    @Test
    public void verifyResponse() throws ExecutionException, InterruptedException {
         Future<Response> futureResponse = Dsl.asyncHttpClient().prepareGet("https://reqres.in/api/users?delay=5").execute();
         Response response = futureResponse.get();

         System.out.println("Response :" + response);

         Assert.assertEquals(200, response.getStatusCode());
         Assert.assertTrue(response.toString().contains("george.bluth@reqres.in"));

    }
}

API Automation with REST Assured, Cucumber and TestNG

HOME

Cucumber is not an API automation tool, but it works well with other API automation tools.

There are 2 most commonly used Automation Tools for JVM to test API – Rest-Assured and Karate. In this tutorial, I will use RestAssured with Cucumber and TestNG for API Testing.

What is Rest Assured?

REST Assured is a Java library that provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful APIs. REST Assured can be used easily in combination with existing unit testing frameworks, such as JUnit and TestNG. Rest assured, no matter how complex the JSON structures are, Rest Assured has methods to retrieve data from almost every part of the request and response.

What is Cucumber?

Cucumber is one such open-source tool, which supports Behaviour Driven Development(BDD). In simple words, Cucumber can be defined as a testing framework, driven by plain English. It serves as documentation, automated tests, and development aid – all in one.

Each scenario is a set of steps that the Cucumber must complete. Cucumber validates the software’s compliance with the specification and generates a report indicating success or failure for each scenario.

The cucumber must adhere to some basic syntax rules known as Gherkin to comprehend the scenarios.

In this tutorial, I will explain creating a framework for the testing of Rest API in Cucumber BDD.

Dependency List

  1. Cucumber – 7.18.0
  2. Java 17
  3. TestNG – 7.10.2
  4. Maven – 3.9.6
  5. Rest Assured – 5.4.0
  6. Maven Compiler – 3.13.0
  7. Maven Surefire – 3.2.5

Project Structure

Step 1 – Download and Install Java

Cucumber and Rest-Assured need Java to be installed on the system to run the tests. Click here to learn How to install Java.

Step 2 – Download and setup Eclipse IDE on the system

The Eclipse IDE (integrated development environment) provides strong support for Java developers. Click here to learn How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add several dependencies to the project. Click here to learn How to install Maven.

Step 4 – Create a new Maven Project

File -> New Project-> Maven-> Maven project-> Next -> Enter Group ID & Artifact ID -> Finish

Click here to learn How to create a Maven project

Step 5 – Install the Cucumber Eclipse plugin for the Eclipse project (Eclipse Only)

The Cucumber plugin is an Eclipse plugin that allows Eclipse to understand the Gherkin syntax. Cucumber Eclipse Plugin highlights the keywords present in the Feature File. To install Cucumber Eclipse Plugin, please refer to this tutorial – How to install Cucumber Eclipse Plugin.

Step 6 – Create source folder src/test/resources

A new Maven Project is created with 2 folders – src/main/java and src/test/java. To create test scenarios, we need a new source folder called – src/test/resources. To create this folder, right-click on your Maven project ->select New ->Java, and then Source Folder.

Mention the source folder name as src/test/resources and click the Next button. This will create a source folder under your new Maven project.

Step 7 – Add dependencies to the project

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <rest.assured.version>5.4.0</rest.assured.version>
    <cucumber.version>7.18.0</cucumber.version>
    <testng.version>7.10.2</testng.version>
    <maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <maven.surefire.plugin.version>3.2.5</maven.surefire.plugin.version>
  </properties>

  <dependencies>

    <!-- Rest Assured -->
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>${rest.assured.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Cucumber with TestNG -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-testng</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <!-- Cucumber with Java -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <!-- TestNG -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

Step 8 – Add Maven Compiler Plugin and Surefire Plugin

The compiler plugin is used to compile the source code of a Maven project. This plugin has two goals, which are already bound to specific phases of the default lifecycle:

  • compile – compile main source files
  • testCompile – compile test source files
 <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.plugin.version}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>
        <configuration>
          <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
          </suiteXmlFiles>
        </configuration>
      </plugin>
    </plugins>
  </build>

The complete POM.xml will look like something below:

<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>com.example</groupId>
  <artifactId>RestAPI_Cucumber_TestNG_Demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>RestAPI_Cucumber_TestNG_Demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <rest.assured.version>5.4.0</rest.assured.version>
    <cucumber.version>7.18.0</cucumber.version>
    <testng.version>7.10.2</testng.version>
    <maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <maven.surefire.plugin.version>3.2.5</maven.surefire.plugin.version>
  </properties>

  <dependencies>

    <!-- Rest Assured -->
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>${rest.assured.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Cucumber with TestNG -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-testng</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <!-- Cucumber with Java -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>${cucumber.version}</version>
    </dependency>

    <!-- TestNG -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.plugin.version}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>
        <configuration>
          <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
          </suiteXmlFiles>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Step 9 – Create a feature file under src/test/resources

Create a folder with name features. Now, create the feature file in this folder. The feature file should be saved with the extension .feature. This feature file contains the test scenarios created to test the application. The Test Scenarios are written in Gherkins language in the format of Given, When, Then, And, But.

Below is an example of a Test Scenario where we are using the GET method to get the information from the API.

Feature: Validation of get method

  @GetUserDetails
  Scenario Outline: Send a valid Request to get user details

    Given I send a request to the URL to get user details
    Then the response will return status <statusCode> and id <id> and email "<employee_email>" and first name "<employee_firstname>" and last name "<employee_lastname>"

    Examples:
    | statusCode | id  | employee_email          | employee_firstname | employee_lastname |
    | 200        | 2   | janet.weaver@reqres.in  | Janet              | Weaver            |

Step 10 – Create the Step Definition class or Glue Code

StepDefinition acts as an intermediate to your runner and feature file. It stores the mapping between each step of the scenario in the Feature file. So when you run the scenario, it will scan the step definition file to check the matched glue or test code.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

public class APIDemoDefinitions {

    private ValidatableResponse validatableResponse;
    private String endpoint = "https://reqres.in/api/users/2";

    @Given("I send a request to the URL to get user details")
    public void sendRequest(){
        validatableResponse = given().contentType(ContentType.JSON)
                .when().get(endpoint).then();

        System.out.println("Response :"+validatableResponse.extract().asPrettyString());
    }

    @Then("the response will return status {int} and id {int} and email {string} and first name {string} and last name {string}")
    public void verifyStatus(int expectedStatusCode, int expectedId, String expectedEmail, String expectedFirstName, String expectedLastName){

        validatableResponse.assertThat().statusCode(expectedStatusCode).body("data.id",equalTo(expectedId)).and()
                .body("data.email",equalTo(expectedEmail)).body("data.first_name",equalTo(expectedFirstName))
                .body("data.last_name",equalTo(expectedLastName));

    }
}

To use REST assured effectively it’s recommended to statically import methods from the following classes:

io.restassured.RestAssured.*
io.restassured.matcher.RestAssuredMatchers.*
org.hamcrest.Matchers.*

Step 11 – Create a TestNG Cucumber Runner class

A runner will help us run the feature file and act as an interlink between the feature file and the StepDefinition Class.

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(tags = "", features = {"src/test/resources/features"}, glue = {"com.example.stepdefinitions"},
        plugin = {})
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {

}

Note:- The name of the Runner class should end with Test otherwise we can’t run the tests using Command-Line.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
    <test  name="Rest Assured, Cucumber with TestNG Test">
        <classes>
            <class name="com.example.runner.CucumberRunnerTests"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->

Step 13 – Run the tests from TestNG

You can execute the test script by right-clicking on TestRunner class -> Run As TestNG (Eclipse).

Step 16 – Run the tests from the Command Line

Run the below command in the command prompt to run the tests and to get the test execution report.

mvn clean test

Step 17 – Cucumber Report Generation

To get Cucumber Test Reports, add cucumber.properties under src/test/resources and add the below instruction in the file.

cucumber.publish.enabled=true

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

How to pass Access token generated by OAuth2 to a request in API Testing

HOME


public class AbstractHelper {
    
   String token;
   String accessToken;
   JsonPath jsonPath;

    public String generateToken() throws IOException {

        token = given().auth().preemptive()
                .basic(username, password)
                .contentType("application/x-www-form-urlencoded")
                .formParam("grant_type", "client_credentials")
                .when().post("https://example.com/accesstoken").asString();

        System.out.println("Token :" + token);

        jsonPath = new JsonPath(token);
        accessToken = jsonPath.getString("access_token");
        System.out.println("Access Token :" + accessToken);
        return accessToken;
    }

}

JsonPath jsonPath = new JsonPath(token);
accessToken = jsonPath.getString("access_token");
import java.io.IOException;

public class AccessToken_Example extends AbstractHelper {

    Response response;
    
   @Test
    public void testRequest() throws IOException {

        response = RestAssured.given()
                .auth().oauth2(generateToken())
                .when().get("https://localhost/8080/coreid").then()
                .extract()
                .response();

        System.out.println("Response :" + response.asString());
        int statusCode = response.getStatusCode();

        Assert.assertEquals(200,statusCode);
    }
}

How to pass authorization token in header in Rest assured?

HOME

 <dependencies>

       <!-- Rest Assured Dependency -->
      <dependency>
         <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
      </dependency>

        <!-- TestNG Dependency-->
      <dependency>
          <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>7.8.0</version>
         <scope>test</scope>
       </dependency>

</dependencies>

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.Assert;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.given;

public class BasicAuth_Demo {


    @Test
    public void createUser() {
        Response response = given()
                .auth()
                .preemptive()
                .header("Authorization", "Token")
                .header("Accept", "application/json")
                .contentType(ContentType.JSON)
                .body(validRequest)
                .when()
                .post("http://localhost:8080/users")
                .then()
                .extract()
                .response();

        int statusCode = response.getStatusCode();

        Assert.assertEquals(statusCode,200);
    }
}

package org.example;

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.junit.Before;
import org.junit.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class BasicAuth_Demo {

    private static final String BASE_URL = "https://httpbin.org/basic-auth/user/pass";
    private static final String TOKEN = "Basic dXNlcjpwYXNz";

    @Before
    public void setup() {
        given().baseUri(BASE_URL);
    }

    @Test
    public void validateToken() {

        Response response = given()
                .header("Accept", "application/json")
                .header("Authorization",TOKEN)
                .contentType(ContentType.JSON)
                .when()
                .get("https://httpbin.org/basic-auth/user/pass")
                .then()
                .log().all()
                .extract()
                .response();

        assertThat(response.getStatusCode(),equalTo(200));

    }

}

How to send basic authentication credentials in Rest Assured

HOME

 <dependencies>

       <!-- Rest Assured Dependency -->
      <dependency>
         <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.3.2</version>
        <scope>test</scope>
      </dependency>

        <!-- TestNG Dependency-->
      <dependency>
          <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>7.8.0</version>
         <scope>test</scope>
       </dependency>

</dependencies>

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.Assert;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.given;

public class BasicAuth_Demo {

   private String validRequest = "{" +
           "\"username\": \"Samu01\"," +
           "\"email\": \"samuel@email.com\"," +
           "\"password\": \"Passw0rd123!\"" +
           "}";

    @Test
    public void createUser() {
        Response response = given()
                .auth()
                .preemptive()
                .basic("username", "password")
                .header("Accept", "application/json")
                .contentType(ContentType.JSON)
                .body(validRequest)
                .when()
                .post("http://localhost:8080/users")
                .then()
                .extract()
                .response();

        int statusCode = response.getStatusCode();

        Assert.assertEquals(statusCode,200);
    }
}

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.junit.Assert;
import org.junit.Test;

import static io.restassured.RestAssured.given;

public class BasicAuth_Demo {

    @Test
    public void validateCredentials() {

        Response response = given()
                .auth()
                .preemptive()
                .basic("user", "pass")
                .header("Accept", "application/json")
                .contentType(ContentType.JSON)
                .when()
                .get("https://httpbin.org/basic-auth/user/pass")
                .then()
                .log().all()
                .extract()
                .response();

        int statusCode = response.getStatusCode();

        Assert.assertEquals(200,statusCode);
    }

given()
    .auth()
    .preemptive()
    .basic("username", "password")