Integration of REST Assured with JUnit4

HOME

In this tutorial, I’ll create a Test Framework for the testing of REST API using REST Assured and JUnit4 as the test framework.

What is Rest Assured?

Rest Assured enables you to test REST APIs using java libraries and integrates well with Maven/Gradle. REST Assured is a Java library that provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful APIs.

What is JUnit?

JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks. JUnit 4 is one of the most popular unit testing frameworks which has a significant role in the test-driven development process.

Dependency List:-

  1. REST Assured – 5.4.0
  2. Java 17
  3. JUnit – 4.13.2
  4. Maven – 3.9.6

Detailed Step Description

Step 1- Download and Install Java

Java needs to be present on the system to run the tests. Click here to know How to install Java. To know if Java is installed or not on your machine, type this command in the command line. This command will show the version of Java installed on your machine.

java -version

Step 2 – Download and setup Eclipse IDE on the system

The Eclipse IDE (integrated development environment) provides strong support for Java developers, which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is a very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool that is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

To know if Maven is already installed or not on your machine, type this command in the command line. This command will show the version of Maven installed on your machine.

mvn -version

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – RestAssured_JUnit4_Demo
Version – 0.0.1-SNAPSHOT
Package – com. example.RestAssured_JUnit4_Demo

Step 5 – Add REST Assured and JUnit4 dependencies to the project

Add the below-mentioned dependencies to the project.

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

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

  <properties>
    <rest-assured.version>5.4.0</rest-assured.version>
    <junit.version>4.13.2</junit.version>
    <json.version>20231013</json.version>
    <hamcrest.version>1.3</hamcrest.version>
    <maven.site.plugin.version>4.0.0-M13</maven.site.plugin.version>
    <maven.compiler.plugin.version>3.12.1</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.2.3</maven.surefire.plugin.version>
    <maven.surefire.report.plugin.version>3.2.5</maven.surefire.report.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>

    <!-- JSON Dependency -->
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>${json.version}</version>
    </dependency>

    <!-- Hamcrest Dependency -->
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-all</artifactId>
      <version>${hamcrest.version}</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>${maven.site.plugin.version}</version>
      </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>

      <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>
    </plugins>
  </build>

  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
        <version>${maven.surefire.report.plugin.version}</version>
      </plugin>
    </plugins>
  </reporting>
</project>

Step 6 – Create the TEST file

The tests should be written in src/test/java directory. To know how to create a JSON Request body using JSONObject, please refer to this tutorial.

import io.restassured.http.ContentType;
import org.json.JSONObject;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static io.restassured.RestAssured.given;

public class APITests {

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


    @Test
    public void createUser() {

        JSONObject data = new JSONObject();

        data.put("employee_name", "NewUser1");
        data.put("employee_salary", "1000");
        data.put("employee_age", "35");

        // GIVEN
        given()
                .contentType(ContentType.JSON)
                .body(data.toString())

                // WHEN
                .when()
                .post(BaseURL + "/v1/create")

                // THEN
                .then()
                .statusCode(200)
                .body("data.employee_name", equalTo("NewUser1"))
                .body("message", equalTo("Successfully! Record has been added."));

    }

}

Step 7 – Test Execution through JUnit Test

Go to the Runner class and right-click Run As JUnit Test. The tests will run as JUnit tests. (Eclipse)

Below is the image to run the tests in IntelliJ.

This is how the execution console will look like.

Step 8 – Run the tests from the command line

Maven Site Plugin creates a folder – site under the target directory, and the Maven Surefire Report plugin generates the JUnit Reports in the site folder. We need to run the tests through the command line to generate the JUnit Report.

mvn clean test site

The output of the above program is

Step 9 – Report Generation

After the test execution, refresh the project, and a new folder with the name site in the target folder will be generated. This folder contains the reports generated by JUnit. The structure of the folder site looks as shown below.

Step 10 – View the Report

Right-click on the summary.html report and select Open In -> Browser ->Chrome.

Summary Report

Below is the summary Report.

Surefire Report

Below is an example of a Surefire Report. This report contains a summary of the test execution.

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

Integration of Serenity with Rest Assured

HOME

In this tutorial, I will explain the Integration of Serenity BDD with Rest Assured for the testing of RestFul API.

What is Serenity BDD?

Serenity BDD is an open-source library that aims to make the idea of living documentation a reality.

What is Rest Assured?

Rest Assured is one of the most powerful libraries for testing RESTful API using Java language. Rest-Assured is a Java-based library that is used to test RESTful Web Services. This library behaves like a headless Client to access REST web services. The rest-Assured library also provides the ability to validate the HTTP Responses received from the server. 

Prerequisite

  1. Java 17 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

Dependency List

  1. Java 17
  2. Maven – 3.9.5
  3. Serenity – 4.0.18
  4. Serenity Rest Assured – 4.0.18
  5. Rest Assured – 5.3.2
  6. JUnit – 4.13.2
  7. Maven Surefire Plugin – 3.1.2
  8. Maven Failsafe Plugin – 3.1.2
  9. Maven Compiler Plugin – 3.11.0

Project Structure

Step 1 – Update the Properties section in Maven pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <serenity.version>4.0.18</serenity.version>
    <serenity.maven.version>4.0.18</serenity.maven.version>
    <junit.version>4.13.2</junit.version>
    <rest.assured.version>5.3.2</rest.assured.version>
    <json.version>20231013</json.version>
    <maven.surefire.plugin.version>3.1.2</maven.surefire.plugin.version>
    <maven.failsafe.plugin.version>3.1.2</maven.failsafe.plugin.version>
    <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <tags></tags>
  </properties>

Step 2 – Add dependencies to POM.xml

<dependencies>
   <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-core</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-junit</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
      
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-screenplay-rest</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-rest-assured</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>${rest.assured.version}</version>
            <scope>test</scope>
        </dependency>
         
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>  
  
       <dependency>
           <groupId>org.json</groupId>
           <artifactId>json</artifactId>
           <version>${json.version}</version>
        </dependency> 
        
    </dependencies>

Step 3 – Update the Build Section of pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*.java</include>
                        <include>**/*.Tests</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <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>net.serenity-bdd.maven.plugins</groupId>
               <artifactId>serenity-maven-plugin</artifactId>
               <version>${serenity.version}</version>
               <dependencies> 
                  <dependency>
                       <groupId>net.serenity-bdd</groupId>
                       <artifactId>serenity-single-page-report</artifactId>
                       <version>${serenity.version}</version>
                  </dependency>                
               </dependencies>
               <configuration>
                   <tags>${tags}</tags>
                   <reports>single-page-html</reports> 
               </configuration>
               <executions>
                  <execution>
                      <id>serenity-reports</id>
                      <phase>post-integration-test</phase>
                      <goals>
                          <goal>aggregate</goal>
                      </goals>
                   </execution>
               </executions>
           </plugin>
        </plugins>
    </build>

Step 4 – Create the Test Code in src/java/test directory

There are 2 ways to create the same test. One approach is to have a Definition file that contains all the test code as shown below.

package org.example.tests;

import io.restassured.response.Response;
import net.serenitybdd.rest.SerenityRest;
import org.json.JSONObject;
import org.junit.Test;

import static org.hamcrest.Matchers.equalTo;

public class Employee {
    private static final String URL = "https://reqres.in/api";
    public Response response;

    int id = 2;

    @Test
    public void verifyValidUser() {

        response = SerenityRest
                .given()
                .contentType("application/json")
                .header("Content-Type", "application/json")
                .when()
                .get(URL + "/users/" + id);

        SerenityRest.restAssuredThat(response -> response.statusCode(200)
                .body("data.id", equalTo(2))
                .body("data.email", equalTo("janet.weaver@reqres.in"))
                .body("data.first_name", equalTo("Janet"))
                .body("data.last_name", equalTo("Weaver")));

    }

    @Test
    public void verifyCreateUser() {
        JSONObject data = new JSONObject();

        data.put("name", "Test");
        data.put("job", "Test Architect");

        response = SerenityRest
                .given()
                .contentType("application/json")
                .header("Content-Type", "application/json")
                .body(data.toString())
                .when()
                .post(URL + "/users");

        SerenityRest.restAssuredThat(response -> response.statusCode(201)
                .body("name", equalTo("Test"))
                .body("job", equalTo("Test Architect")));

    }

}

Another approach is that all tests are split into reusable blocks called “steps“. The main principle of the BDD approach is that we are trying to keep complexity to a high-level human-readable level. First of all, let’s create a separate package to keep our steps. It is always better to keep them separate as it shows which classes contain reusable components. It is better to make steps smaller. So let’s make separate reusable steps from our tests:

package org.example.steps;

import io.restassured.response.Response;
import net.serenitybdd.annotations.Step;
import net.serenitybdd.rest.SerenityRest;
import org.json.JSONObject;

import static org.hamcrest.Matchers.equalTo;

public class EmployeeSteps {
    private static final String URL = "https://reqres.in/api";
    public Response response;

    @Step("Search user by id {0}")
    public void sendUser(int id) {
        response = SerenityRest
                .given()
                .contentType("application/json")
                .header("Content-Type", "application/json")
                .when()
                .get(URL + "/users/" + id);

    }

    @Step("Create a new user")
    public void createUser() {

        JSONObject data = new JSONObject();

        data.put("name", "Test");
        data.put("job", "Test Architect");

        response = SerenityRest
                .given()
                .contentType("application/json")
                .header("Content-Type", "application/json")
                .body(data.toString())
                .when()
                .post(URL + "/users");

    }

    @Step("Verify the status code {0}")
    public void verifyStatusCode(int expectedStatusCode) {
        SerenityRest.restAssuredThat(response -> response.statusCode(expectedStatusCode));
    }

    @Step("Verify the user id {0}")
    public void verifyId(int expectedId) {
        SerenityRest.restAssuredThat(response -> response.body("data.id", equalTo(expectedId)));
    }

    @Step("Verify the user first name {0}")
    public void verifyFirstName(String expectedFirstName) {

        SerenityRest.restAssuredThat(response -> response.body("data.first_name", equalTo(expectedFirstName)));
    }

    @Step("Verify the user last name {0}")
    public void verifyLastName(String expectedLastName) {
        SerenityRest.restAssuredThat(response -> response.body("data.last_name", equalTo(expectedLastName)));
    }

    @Step("Verify the user email {0}")
    public void verifyEmail(String expectedEmail) {
        SerenityRest.restAssuredThat(response -> response.body("data.email", equalTo(expectedEmail)));
    }

    @Step("Verify the new user name {0}")
    public void verifyNewUserName(String expectedName) {
        SerenityRest.restAssuredThat(response -> response.body("name", equalTo(expectedName)));
    }

    @Step("Verify the new user job {0}")
    public void verifyNewUserJob(String expectedJob) {
        SerenityRest.restAssuredThat(response -> response.body("job", equalTo(expectedJob)));
    }

}

Now our steps are ready. Let’s refactor the main class with our tests:

package org.example.tests;

import net.serenitybdd.annotations.Steps;
import net.serenitybdd.annotations.Title;
import net.serenitybdd.junit.runners.SerenityRunner;
import org.example.steps.EmployeeSteps;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(SerenityRunner.class)
public class EmployeeTests {
    @Steps
    EmployeeSteps employeeSteps;

    @Test
    @Title("Get User")
    public void verifyValidUser() {
        employeeSteps.sendUser(2);
        employeeSteps.verifyStatusCode(200);
        employeeSteps.verifyId(2);
        employeeSteps.verifyFirstName("Janet");
        employeeSteps.verifyLastName("Weaver");
        employeeSteps.verifyEmail("janet.weaver@reqres.in");

    }

    @Test
    @Title("Create User")
    public void createValidUser() {

        employeeSteps.createUser();
        employeeSteps.verifyStatusCode(201);
        employeeSteps.verifyNewUserName("Test");
        employeeSteps.verifyNewUserJob("Test Architect");

    }

}

One more important thing we added is the @RunWith(SerenityRunner.class)” annotation on top of the class. As we have now organized our structure to meet some basic Serenity principles, we are ready to run the test using Serenity. This time (after we added the mentioned annotation) these tests will be run using the “SerenityRunner”. For that we can use exactly the same command to run our tests:

mvn clean verify

The output of the above program is

In the console, you should find printed messages for tests to start. At the same time under the target directory you can find the HTML-generated report we were talking about before:

You can open the report in any browser:

If you click on any test you should see a detailed description of the test steps:

One of the most important features of the Serenity and REST Assured integration is that by using detailed reporting, you can easily validate all requests and response details even if you are not adding any logs inside tests. Like the example above, for each executed REST request you can click the button “REST Query” and get a detailed request and response description:

There is another very useful Serenity Report – Serenity Symmary.html

As you can see, Serenity and REST Assured provide you with a wonderful combination. REST Assured keeps API testing clean and easy to maintain, while Serenity gives you outstanding test reporting and flexibility in running and grouping your tests inside a test suite.

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

Serenity BDD with Cucumber and Rest Assured

 

HOME

What is Serenity BDD?

Serenity BDD is an open-source library that aims to make the idea of living documentation a reality.

What is Rest Assured?

Rest Assured is one of the most powerful libraries for testing RESTful API using Java language. Rest-Assured is a Java-based library that is used to test RESTful Web Services. This library behaves like a headless Client to access REST web services. The Rest-Assured library also provides the ability to validate the HTTP Responses received from the server. For e.g. we can verify the Status code, Status message, Headers, and even the Body of the response. This makes Rest-Assured a very flexible library that can be used for testing. In this post, we will learn how to write high-quality, expressive REST API tests using Rest Assured and Serenity BDD.

Prerequisite

  1. Java 17 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

Dependency List:

  1. Java 17
  2. Maven – 3.9.5
  3. Serenity – 4.0.18
  4. Serenity Rest Assured – 4.0.18
  5. Serenity Cucumber – 4.0.18
  6. Rest Assured – 5.3.2
  7. JUnit – 4.13.2
  8. Maven Surefire Plugin – 3.2.1
  9. Maven Failsafe Plugin – 3.2.1
  10. Maven Compiler Plugin – 3.11.0

Project Structure

Step 1 – Update Properties section in Maven pom.xml

 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <serenity.version>4.0.18</serenity.version>
        <serenity.cucumber.version>4.0.18</serenity.cucumber.version>
        <rest.assured.version>5.3.2</rest.assured.version>
        <junit.version>4.13.2</junit.version>
        <maven.compiler.plugin.version>3.11.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.1</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.2.1</maven.failsafe.plugin.version>
        <tags></tags>
    </properties>

Step 2 – Add dependencies to POM.xml

 <dependencies>

      <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-core</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
      </dependency>

      <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-cucumber</artifactId>
        <version>${serenity.cucumber.version}</version>
        <scope>test</scope>
      </dependency>

      <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-rest-assured</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
      </dependency>

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

      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
      </dependency>

    </dependencies>

Step 3 – Update the Build Section of pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*.java</include>
                    </includes>
                    <parallel>methods</parallel>
                    <useUnlimitedThreads>true</useUnlimitedThreads>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <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>net.serenity-bdd.maven.plugins</groupId>
                <artifactId>serenity-maven-plugin</artifactId>
                <version>${serenity.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>net.serenity-bdd</groupId>
                        <artifactId>serenity-single-page-report</artifactId>
                        <version>${serenity.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <tags>${tags}</tags>
                    <reports>single-page-html</reports>
                </configuration>
                <executions>
                    <execution>
                        <id>serenity-reports</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

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

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <serenity.version>4.0.18</serenity.version>
        <serenity.cucumber.version>4.0.18</serenity.cucumber.version>
        <rest.assured.version>5.3.2</rest.assured.version>
        <junit.version>4.13.2</junit.version>
        <maven.compiler.plugin.version>3.11.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.1</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.2.1</maven.failsafe.plugin.version>
        <tags></tags>
    </properties>


    <dependencies>

        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-core</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-cucumber</artifactId>
            <version>${serenity.cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>net.serenity-bdd</groupId>
            <artifactId>serenity-rest-assured</artifactId>
            <version>${serenity.version}</version>
            <scope>test</scope>
        </dependency>

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

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven.failsafe.plugin.version}</version>
                <configuration>
                    <includes>
                        <include>**/*.java</include>
                    </includes>
                    <parallel>methods</parallel>
                    <useUnlimitedThreads>true</useUnlimitedThreads>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <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>net.serenity-bdd.maven.plugins</groupId>
                <artifactId>serenity-maven-plugin</artifactId>
                <version>${serenity.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>net.serenity-bdd</groupId>
                        <artifactId>serenity-single-page-report</artifactId>
                        <version>${serenity.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <tags>${tags}</tags>
                    <reports>single-page-html</reports>
                </configuration>
                <executions>
                    <execution>
                        <id>serenity-reports</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>aggregate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Step 4 – Create a Feature file in src/test/resources 

Create a features folder within src/test/resources to create test scenarios in the Feature file. Test Scenarios are created in a Feature File which contains an overall description of a feature as well as a number of scenarios. Feature files can be placed in different locations, but you can reduce the amount of configuration you need to do with serenity if you put them in the src/test/resources/features directory. In this feature file, will send a request, and the response should be of status “200” and employee name of “Tiger Nixon”. The feature file looks something like this:

Feature: Employee Details

  @GetEmployee
  Scenario: Get the details of employee
    Given I send a request to endpoint
    Then the API should return status 200
    And Response should contains employee name "Tiger Nixon"

Step 5 – Create the Step Definition class or Glue Code

To use Rest-assured, Serenity provides class SerenityRest

import net.serenitybdd.rest.SerenityRest;

 It is a Java method with an expression that is used to link it to Gherkin steps. When Cucumber executes a Gherkin step, it will look for a matching step definition to execute. These use annotations like @given, @when, and @then to match lines in the scenario to java methods

package org.example.definitions;

import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.restassured.response.Response;
import net.serenitybdd.rest.SerenityRest;
import static org.hamcrest.Matchers.equalTo;

public class EmployeeDefinitions {
    private static final String URL = "http://dummy.restapiexample.com/api/v1/employee/1";
    public Response response;

    @Given("I send a request to endpoint")
    public void sendRequest()  {

        response = SerenityRest.given().contentType("application/json").header("Content-Type", "application/json")
                .when().get(URL);
    }

    @Then("the API should return status {int}")
    public void verifyResponse(int status) {
        SerenityRest.restAssuredThat(response -> response.statusCode(status));
    }

    @And("Response should contains employee name {string}")
    public void verifyResponseContent(String expectedEmployeeName) {

        SerenityRest.restAssuredThat(response -> response.body("data.employee_name", equalTo(expectedEmployeeName)));
    }
}

Step 6 – Create Serenity Test Runner

Cucumber runs the feature files via JUnit and needs a dedicated Test Runner class to run the feature files. When you run the tests with serenity, you use the CucumberWithSerenity test runner. If the feature files are not in the same package as the test runner class, you also need to use the @CucumberOptions class to provide the root directory where the feature files can be found. It is the starting point for JUnit to start executing the tests. TestRunner class is created under src/test/java. The test runner to run all of the feature files looks like this:

import org.junit.runner.RunWith;

import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;

@RunWith(CucumberWithSerenity.class)
@CucumberOptions(plugin = { "pretty" }, features = "src/test/resources/features/Employee.feature", glue = {
		"org.example.definitions" })

public class SerenityAPITestRunner {

}

serenity.project.name = Rest API Testing using Serenity, Cucumber and JUnit4

Step 8 – Serenity Tests Execution

You can run the tests from SerenityAPITestRunner or from the command line by

mvn clean verify

Test Execution Page looks like this as shown below image

Step 9 – Verify the Serenity Reports

A number of reports are generated, but we are concerned about index.html and serenity-summary.html.

The report is well-formatted and contains consolidated results. Reporting is one of the major pillars of Serenity. Serenity Report not only reports on whether a test scenario passes or fails but documents what it did, in a step-by-step narrative format. The below pic illustrates the test results for our first acceptance criteria:

The test report generated by Serenity is placed under target/site/serenity/index.html. 

Index.html

The first tab is called “Overall Test Results” and it provides information about test statistics. This Overall Test Result shows the Scenario Results (No Of Test Cases Pass, No Of Test Cases Failed, No of Test Cases Pending, No Of Test Cases Ignored, No Of Test Cases Skipped). 

In the below pic, the report shows the test scenario steps status and time taken for each step to execute. 

With the use of the REST Query button, it’s possible to display query details. Visible details:

Path, Status code, Request Headers, Request Body, Request Cookies, Response Headers, Response Body.

There is also the “Requirements” tab. When we have tests as part of our code base, all test results will be organized as associated with requirements. 

There is also a “Features” tab. This page lists all the features that are part of your suite.  If you expand that row you’ll see the bit of narrative text that is part of the current feature file. 

Serenity-Summary.html

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

Additional Tutorials:

Serenity BDD with Cucumber for Web Application
Serenity BDD with Cucumber for SpringBoot Application
How to manage screenshots in Serenity Report
Serenity Report for Web Application with Cucumber6 and Junit
 Integration of Serenity with Cucumber6 and JUnit5
Serenity BDD with Gradle and Cucumber for Web Application

How to test POST JSON Object request using Java Map in Rest Assured

HOME

In the last tutorial, I explained How to test POST request from JSON Object in Rest Assured where the request body is built in JSONObject. In this tutorial, I will create a request body using JSON Object in Rest Assured. 

We can create a JSON Object using a Map in Java. A JSON Object is a key-value pair and can be easily created using a Java Map. A Map in Java also represents a collection of key-value pairs.

<dependencies>

    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20231013</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.15.2</version>
    </dependency>

  </dependencies>

I have created a simple Java map and filled it with the values that represent JSON properties.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;

public class Json_Demo {

    @Test
    public void passBodyAsMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("employee_name", "MapTest");
        map.put("employee_salary", "99999");
        map.put("employee_age", "30");
        map.put("profile_image", "test.png");
        RestAssured.given()
                .contentType(ContentType.JSON)
                .body(map)
                .log().all()

                .when()
                .post("https://dummy.restapiexample.com/api/v1/create")

                .then()
                .assertThat().statusCode(200)
                .body("data.employee_name", equalTo("MapTest"))
                .body("data.employee_age", equalTo("30"))
                .body("data.employee_salary", equalTo("99999"))
                .body("message", equalTo("Successfully! Record has been added.")).log().all();
    }
}

The request body as well as the response body will look as shown below:-

Above one is a simple JSON Request Body. Let us take an example of a Complex Request Body or nested Request Body as shown below.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;

public class Json_Demo {

    @Test
    public void passBodyAsMultipleMap() {

        // First JSON Object using Hash Map
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("employee_name", "MapTest");
        data.put("profile_image", "test.png");

        // Second JSON Object using Hash Map
        Map<String, String> msg = new HashMap<String, String>();
        msg.put("updated_message", "Details of New Resource");
        msg.put("employee_age", "30");
        data.put("details", msg);
        data.put("employee_salary", "99999");
        RestAssured.given().contentType(ContentType.JSON).body(data).log().all()
                // WHEN
                .when().post("https://dummy.restapiexample.com/api/v1/create")
                // THEN
                .then().assertThat().statusCode(200).body("data.employee_name", equalTo("MapTest"))
                .body("data.details.updated_message", equalTo("Details of New Resource"))
                .body("data.details.employee_age", equalTo("30")).body("data.employee_salary", equalTo("99999"))
                .body("message", equalTo("Successfully! Record has been added.")).log().all();
    }
}

The request body as well as the response body will look as shown below image. The first part is the body of the request and the second part is the response provided by the API.

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

How to test PATCH Request using Rest Assured

HOME

In the last tutorial, I explained How to test POST Request using Rest Assured. In this tutorial, I will automate a PATCH Request using Rest Assured. I will verify the status code, line of Status, and content of the Response.

To set up a basic Rest Assured Maven Project, click here and Gradle project, click here.

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
</dependency>
  
<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
</dependency>

What is the PATCH Method?

The HTTP PATCH request method applies partial modifications to a resource

Below are the steps to test a PATCH Request using Rest Assured:

The steps to test the PATCH request are similar to the PUT request.

Below is the example for the test to PATCH method. (Non BDD)

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;

public class Patch_NonBDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void updateUser() {

        String jsonString = "{\"name\": \"William\"}";

        RestAssured.baseURI = "https://reqres.in/api/users/2";

        // Create a request specification
        requestSpecification = RestAssured.given();

        // Setting content type to specify format in which request payload will be sent.
        requestSpecification.contentType(ContentType.JSON);

        // Adding body as string
        requestSpecification.body(jsonString);

        // Calling PATCH method
        response = requestSpecification.patch();

        // Let's print response body.
        String responseString = response.prettyPrint();

        /*
         * To perform validation on response, we need to get ValidatableResponse type of
         * response
         */
        validatableResponse = response.then();

        // Get status code
        validatableResponse.statusCode(200);

        // It will check if status line is as expected
        validatableResponse.statusLine("HTTP/1.1 200 OK");

        // Check response - name attribute
        validatableResponse.body("name", equalTo("William"));

    }
}

Test implemented in BDD Format

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;

public class Patch_BDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void updateUser() {

       String jsonString = "{\"name\": \"William\"}";

        // Update name
        validatableResponse = given()
                .baseUri("https://reqres.in/api/users/2")
                .contentType(ContentType.JSON)
                .body(jsonString)
                .when()
                .patch()
                .then()
                .assertThat().statusCode(200)
                .body("name", equalTo("William"));

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

    }

}

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

How to test DELETE in Rest Assured

HOME

In the last tutorial, I explained How to test PUT Request using Rest Assured. In this tutorial, I will automate a DELETE Request using Rest Assured. I will verify the status code, line of Status, and content of the Response.

To set up a basic Rest Assured Maven Project, click here and Gradle project, click here.

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
</dependency>
  
<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
</dependency>

What is the DELETE Method?

An HTTP DELETE method is used to delete an existing resource from the collection of resources. The DELETE method requests the origin server to delete the resource identified by the Request-URI. On successful deletion of a resource, it returns  200 (OK) and 204 (No Content) status codes. It may return as 202 (Accepted) status code if the request is queued. To learn more about Rest API, please click here.

Below are the steps to test a DELETE Request using Rest Assured:

The steps to test the DELETE request are similar to any API request like GET, POST, or PUT. To know about the steps and various imports used in the below example in detail, please refer to the tutorial for POST Request.

Let’s see the existing details of an Employee ID 3 using Postman:

Let’s write DELETE request in REST Assured in Non BDD Format for id 3:-

import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;

public class Delete_NonBddDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void deleteUser() {

        RestAssured.baseURI = "https://dummy.restapiexample.com/api";

        // Create a request specification
        requestSpecification = RestAssured.given();

        // Calling DELETE method
        response = requestSpecification.delete("/v1/delete/3");

        // Let's print response body.
        String resString = response.prettyPrint();

        /*
         * To perform validation on response, we need to get ValidatableResponse type of
         * response
         */
        validatableResponse = response.then();

        // Get status code
        validatableResponse.statusCode(200);

        // It will check if status line is as expected
        validatableResponse.statusLine("HTTP/1.1 200 OK");

        // Check response - message attribute
        validatableResponse.body("message", equalTo("Successfully! Record has been deleted"));

    }
}

Let’s write DELETE request in REST Assured in BDD Format:

import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse;
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;

public class Delete_BDDDemo {

    ValidatableResponse validatableResponse;

    @Test
    public void deleteUser() {
        
        validatableResponse = given()
                .baseUri("https://dummy.restapiexample.com/api/v1/delete/3")
                .contentType(ContentType.JSON)
                .when()
                .delete()
                .then()
                .assertThat().statusCode(200)
                .body("message", equalTo("Successfully! Record has been deleted"));

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

    }

}

.baseUri("https://dummy.restapiexample.com/api/v1/delete/3")
  .contentType(ContentType.JSON)
assertThat().statusCode(200)
.body("message", equalTo("Successfully! Record has been deleted"));

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

How to test PUT Request using Rest Assured

HOME

In the last tutorial, I explained How to test POST Request using Rest Assured. In this tutorial, I will automate a PUT Request using Rest Assured. I will verify the status code, line of Status, and content of the Response.

To set up a basic Rest Assured Maven Project, click here and Gradle project, click here.

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
</dependency>
  
<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
</dependency>

What is the PUT Method?

The HTTP PUT API is primarily used to update existing resources. If the resource does not exist, then API may decide to create a new resource or not (Depending on API development). If a new resource has been created by the PUT API, the origin server MUST inform the user agent via the HTTP response code 201 (Created) response, and if an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. To learn more about Rest API, please click here.

Below are the steps to test a PUT Request using Rest Assured:

The steps to test the PUT request are similar to the POST request. The only difference is that in POST we send a request to create a new resource, whereas here we have a resource and I will update the detail of the already existing resource. To know about the steps and various imports used in the below example, please refer to the tutorial for POST Request.

Below is the response received for Employee with id 2.

I want to change the employee_salary to 99999. Below is the example for the test to update employee_salary.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;

public class PUT_NonBDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse;

    @Test
    public void updateUser() {

        String jsonString = "{\"id\": 2,\r\n"
                + "        \"employee_name\": \"Garrett Winters\",\r\n"
                + "        \"employee_salary\": 99999,\r\n"
                + "        \"employee_age\": 63,\r\n"
                + "        \"profile_image\": \"\"}";

        RestAssured.baseURI = "https://dummy.restapiexample.com/api/v1/update/2";

        // Create a request specification
        requestSpecification = RestAssured.given();

        // Setting content type to specify format in which request payload will be sent.
        requestSpecification.contentType(ContentType.JSON);

        // Adding body as string
        requestSpecification.body(jsonString);

        // Calling PUT method
        response = requestSpecification.put();

        // Let's print response body.
        String responseString = response.prettyPrint();

        /*
         * To perform validation on response, we need to get ValidatableResponse type of
         * response
         */
        validatableResponse = response.then();

        // Get status code
        validatableResponse.statusCode(200);

        // It will check if status line is as expected
        validatableResponse.statusLine("HTTP/1.1 200 OK");

        // Check response - name attribute
        validatableResponse.body("data.employee_salary", equalTo(99999));

        // Check response - message attribute
        validatableResponse.body("message", equalTo("Successfully! Record has been updated."));

    }
}

Now, let us convert the same test into BDD format. In the below example, in the first part, we have retrieved the details of the employee with ID 2, and in the second part, we have updated the value of employee_salary to 99999.

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;

public class PUT_BDDDemo {

    RequestSpecification requestSpecification;
    Response response;
    ValidatableResponse validatableResponse, validatableResponse1;

    @Test
    public void updateUser() {

        // To get the detail of employee with id 2
        validatableResponse = given()
                .baseUri("https://dummy.restapiexample.com/api/v1/employee/2")
                .contentType(ContentType.JSON)
                .when()
                .get()
                .then()
                .assertThat().statusCode(200);

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

        String jsonString = "{\"id\": 2,\r\n"
                + "        \"employee_name\": \"Garrett Winters\",\r\n"
                + "        \"employee_salary\": 99999,\r\n"
                + "        \"employee_age\": 63,\r\n"
                + "        \"profile_image\": \"\"}";

        // Update employee_salary
        validatableResponse1 = given()
                .baseUri("https://dummy.restapiexample.com/api/v1/update/2")
                .contentType(ContentType.JSON)
                .body(jsonString)
                .when()
                .put()
                .then()
                .assertThat().statusCode(200)
                .body("data.employee_salary", equalTo(99999))
                .body("message", equalTo("Successfully! Record has been updated."));

        System.out.println("Response2 :" + validatableResponse1.extract().asPrettyString());

    }

}

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

Assertion of JSON in Rest Assured using Hamcrest

Last Updated On

HOME

In this tutorial, we will discuss various types of Assertions present in Hamcrest that are used in Rest Assured.

Table Of Contents

What is Assertion?

An assertion is a way to verify that the expected result and the actual result match or not in the test case.  A test is considered successful ONLY if it is completed without throwing any exceptions. If the current value and the expected value match then the assertion passes and when the assertion passes nothing happens. But when an assertion fails, it will fail the test case.

There are various ways to perform assertions in API Testing. For API Testing, we are using Rest Assured, which uses either Hamcrest or JUnit assertions. We are going to discuss Hamcrest Assertions here.

What is Hamcrest?

Hamcrest is a framework for writing matcher objects, allowing ‘match’ rules to be defined declaratively. We do not need to add Hamcrest dependency explicitly as the Rest-Assured 4.3.3 version includes itself. To learn more about Hamcrest, please refer to this link.

We need to add the below dependency to use Hamcrest in the project. Please use the latest version from here

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

To run all the scenarios mentioned below, please add the below-mentioned dependencies to the POM.xml.

<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
    <artifactId>RestAssured_TestNG_Demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <hamcrest.version>3.0</hamcrest.version>
        <testng.version>7.8.0</testng.version>
        <rest-assured.version>5.3.2</rest-assured.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

     <!-- Hamcrest Dependency -->
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest</artifactId>
        <version>${hamcrest.version}</version>
        <scope>test</scope>
    </dependency>

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

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

    </dependencies>
</project>

Below is an example of a JSON Response. I will perform various assertions on this JSON Response.

To use hamcrest assertion, please import the Matchers class, static member.

  1. equalTo – It checks whether the retrieved number from the response is equal to the expected number.
  2. greaterThan – checks extracted number is greater than the expected number.
  3. greaterThanOrEqualTo – checks whether the extracted number is greater than equal to the expected number.
  4. lessThan – It checks whether the retrieved number from the response is lesser than the expected number.
  5. lessThanOrEqualTo – It checks whether the retrieved number from the response is lesser than or equal to the expected number.

Below assertions are imported from the package shown below:-

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.lessThan;

Below are examples to show the use of number-related assertions.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.lessThan;

public class HamcrestNumberExample {

    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";

    @Test
    public void numberAssertions() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint).then()
                .body("totalprice", equalTo(164));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice",greaterThan(100));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice",greaterThanOrEqualTo(50));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice",lessThan(1000));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice",lessThanOrEqualTo(1000));

    }

}

The output of the above program is

  1. equalTo – It checks whether the extracted string from JSON is equal to the expected string.
  2. equalToIgnoringCaseIt checks if the extracted string from JSON matches the expected string. The comparison does not consider case (small or capital).
  3. equalToIgnoringWhiteSpace – It checks if the extracted string from JSON matches the expected string. It takes into account the white spaces.
  4. containsString – It checks whether the extracted string from JSON contains the expected string as a substring.
  5. startsWith It checks whether the extracted string from JSON is starting with a given string or character.
  6. endsWithIt checks whether the extracted string from JSON is ending with a given string or character.

Below assertions are imported from the package shown below:-

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.equalToIgnoringWhiteSpace;

Below are examples to show the use of string-related assertions.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.equalToIgnoringWhiteSpace;

public class HamcrestStringAssertions {

    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";

    @Test
    public void stringAssertions() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",equalTo("Mary"));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",equalToIgnoringCase("mary"));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",containsString("Mary"));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",startsWith("M"));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",endsWith("y"));

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("firstname",equalToIgnoringWhiteSpace("   Mary "));


    }
}

The output of the above program is

nullValue

It checks whether the extracted response from JSON is NULL or Not.

Below assertions are imported from the package shown below:-

import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;

Below are examples to show the use of collection-related assertions.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;

public class HamcrestNullAssertion {
    
   public String endpoint = "https://restful-booker.herokuapp.com/booking/1";

    @Test
    public void nullAssertion() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice1", is(nullValue()));
    }
}

The output of the above program is

hasKey

It checks whether the extracted map has an expected key.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.hasKey;

public class HamcrestHasKeyAssertion {
    
    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";

    @Test
    public void collectionAssertions() {

        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("bookingdates",hasKey("checkin"));

    }
}

The output of the above program is

Not Assertion

The not assertion inverts the meaning of the other assertions. For example, if you want to perform negative assertions, then we can use any assertions with NOT.

The below assertion is imported from the package shown below:-

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;

Below are examples to show the use of negative assertions.

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;

public class HamcrestNotAssertion {
    
    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";

    @Test
    public void negativeAssertions() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint)
                .then().body("totalprice",not(equalTo(874)));

    }
}

The output of the above program is

Multiple Assert Statements

In the below example, all 3 assertions will fail. It will only execute the first assertion. If the first assertion fails, then other assertions will not be executed.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.equalTo;

public class HamcrestMultipleAssertions {

    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";
    
    @Test
    public void test1() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint).then()
                .body("firstname", equalTo("Jim"), // will fail
                        "lastname", equalTo("Smith"), // will fail
                        "totalprice", equalTo(314)); // will fail
    }

}

The output of the above program is

To execute all the assertions in the test case, combine them into a single body. This should be done just like it is shown below. You can see that all the assertions failed, and they are shown in the response.

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.equalTo;

public class HamcrestMultipleAssertions {

    public String endpoint = "https://restful-booker.herokuapp.com/booking/1";
    
    @Test
    public void test1() {
        RestAssured.given().contentType(ContentType.JSON)
                .when().get(endpoint).then()
                .body("firstname", equalTo("Jim"), // will fail
                        "lastname", equalTo("Smith"), // will fail
                        "totalprice", equalTo(314)); // will fail
    }

}

The output of the above program is

I have tried to show the use of a few of the most commonly used assertion methods. There are many more methods available in Hamcrest package. To know about other methods, write import static org.hamcrest.Matchers and add (.) at the end, it will show the list of all the methods available in Hamcrest.

To know more details related to Hamcrest assertion, you can refer the official website – Hamcrest

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

How to test POST JSON Object request using Java Map in Rest Assured
How to create JSON Array Request Body
Extraction from JSON in Rest Assured
How To Send A JSON/XML File As Payload To Request using Rest Assured
Logging in Rest Assured

Rest Assured Tutorials

HOME

RestAssured is a Java-based library that is used to test RESTful Web Services. REST-assured was designed to simplify the testing and validation of REST APIs. It takes influence from testing techniques used in dynamic languages such as Ruby and Groovy.

Chapter 1 Assertion of JSON in Rest Assured using Hamcrest
Chapter 2 Extraction from JSON in Rest Assured – JsonPath
Chapter 3 How to perform multiple assertions in Rest Assured? 
Chapter 4 How to validate JSON body in Rest Assured?
Chapter 5 Compare JSON Objects using JSONAssert Library
Chapter 6 Compare JSON Arrays using JSONAssert Library
Chapter 7 How to Read JSON with JSON.simple – NEW
Chapter 8 How to create and write to JSON with JSON.simple – NEW

JSON Handling and manipulation

Category 10: XML Manipulations

XML Handling and manipulation

Gradle

Chapter 1 Setup Basic REST Assured Gradle Project In Eclipse IDE

Frameworks

Chapter 1 Integration of REST Assured with TestNG
Chapter 2 Integration of REST Assured with JUnit4
Chapter 3 Integration of REST Assured with JUnit5
Chapter 4 Serenity BDD with Cucumber and Rest Assured
Chapter 5 Serenity BDD with Cucumber and Rest Assured in Gradle
Chapter 6 How To Create Gradle Project with Cucumber to test Rest API
Chapter 7 Rest API Test in Cucumber and JUnit4
Chapter 8 API Automation with REST Assured, Cucumber and TestNG

Integration of REST Assured with JUnit5

HOME

In this tutorial, I’ll create a Test Framework for the testing of REST API using REST Assured and JUnit5 as the test framework.

What is Rest Assured?

Rest Assured enables you to test REST APIs using Java libraries and integrates well with Maven/Gradle. REST Assured is a Java library that provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful APIs.

What is JUnit5?

JUnit 5 is the next generation of JUnit. JUnit 5 is composed of several different modules from three different sub-projects.

Dependency List:-

  1. REST Assured – 5.3.2
  2. Java 11
  3. JUnit Jupiter API – 5.10.0
  4. JUnit Jupiter Engine – 5.10.0
  5. Maven – 3.8.1
  6. Json – 20230618

Detailed Step Description

Step 1- Download and Install Java

Java needs to be present on the system to run the tests. Click here to know How to install Java. To know if Java is installed or not on your machine, type this command in the command line. This command will show the version of Java installed on your machine.

java -version

Step 2 – Download and setup Eclipse IDE on the system

The Eclipse IDE (integrated development environment) provides strong support for Java developers, which is needed to write Java code. Click here to learn How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is a very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool that is used to define project structure, dependencies, build, and test management. Click here to learn How to install Maven.

To know if Maven is already installed or not on your machine, type this command in the command line. This command will show the version of Maven installed on your machine.

mvn -version

Step 4 – Create a new Maven Project

Click here to learn How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – RestAssured_JUnit5_Demo
Version – 0.0.1-SNAPSHOT
Package – com. example.RestAssured_JUnit4_Demo

Step 5 – Add REST Assured and JUnit5 dependencies to the project

Add the below-mentioned dependencies to the project.

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

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

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <rest-assurd.version>5.3.2</rest-assurd.version>
    <json.version>20230618</json.version>
    <hamcrest.version>1.3</hamcrest.version>
    <junit5.version>5.10.0</junit5.version>
    <maven.surefire.report.plugin.version>3.1.2</maven.surefire.report.plugin.version>
    <maven.compiler.plugin.version>3.10.1</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.1.2</maven.surefire.plugin.version>
    <maven.compiler.source.version>11</maven.compiler.source.version>
    <maven.compiler.target.version>11</maven.compiler.target.version>
    <maven.site.plugin.version>3.12.0</maven.site.plugin.version>
  </properties>

  <dependencies>

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

    <!-- JUNIT Jupiter API Dependency-->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit5.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- JUNIT Jupiter Engine Dependency-->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>${junit5.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- JSON Dependency -->
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>${json.version}</version>
    </dependency>

    <!-- Hamcrest Dependency -->
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-all</artifactId>
      <version>${hamcrest.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.version}</source>
          <target>${maven.compiler.target.version}</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>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>${maven.site.plugin.version}</version>
      </plugin>
    </plugins>
  </build>

    <reporting>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-report-plugin</artifactId>
          <version>${maven.surefire.report.plugin.version}</version>
          <configuration>
            <outputName>JUnit5 Report</outputName>
          </configuration>
        </plugin>
      </plugins>
    </reporting>

</project>

Step 6 – Create the TEST file

The tests should be written in src/test/java directory. To learn how to create a JSON Request body using JSONObject, please refer to this tutorial.

import io.restassured.http.ContentType;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

public class APITests {

        String BaseURL = "https://reqres.in/api";

    @Test
    public void createUser() {

        JSONObject data = new JSONObject();

        data.put("name", "NewUser1");
        data.put("job", "Testing");

        // GIVEN
        given()
                .contentType(ContentType.JSON)
                .body(data.toString())

                // WHEN
                .when()
                .post(BaseURL + "/users")

                // THEN
                .then()
                .statusCode(201)
                .body("name", equalTo("NewUser1"))
                .body("job", equalTo("Testing"))
                .log().all();

    }

    @Test
    public void getUser() {  //Failed Test

        // GIVEN
        given()
                .contentType(ContentType.JSON)

                // WHEN
                .when()
                .get(BaseURL + "/users/2")

                // THEN
                .then()
                .statusCode(200)
                .body("data.first_name", equalTo("Janet1"))
                .log().all();

    }

}

Step 7 – Test Execution through JUnit Test

Go to the Runner class and right-click Run As JUnit Test. The tests will run as JUnit tests.

Below is the image to run the tests in IntelliJ.

This is how the execution console will look like.

Step 8 – Run the tests from the command line

Maven Site Plugin creates a folder – site under the target directory, and the Maven Surefire Report plugin generates the JUnit Reports in the site folder. We need to run the tests through the command line to generate the JUnit Report.

mvn clean test site

The output of the above program is

Step 9 – Report Generation

After the test execution, refresh the project, and a new folder with the name site in the target folder will be generated. This folder contains the reports generated by JUnit. The structure of the folder site looks as shown below.

View the Report

Right-click on the Junit5 Report.html and select Open In -> Browser ->Chrome.

Summary Report

Below is the summary Report.

Surefire Report

Below is an example of a Surefire Report. This report contains a summary of the test execution.

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