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. Rest-Assured library also provides the ability to validate the HTTP Responses received from the server. 

Pre-Requisite

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

This framework consists of:

  1. Java 11
  2. Maven – 3.8.1
  3. Serenity – 2.6.0
  4. Serenity Rest Assured – 2.6.0
  5. Rest Assured – 4.4.0
  6. JUnit – 4.13.2
  7. Maven Surefire Plugin – 3.0.0-M5
  8. Maven Failsafe Plugin – 3.0.0-M5
  9. Maven Compiler Plugin – 3.8.1

Implementation Steps

  1. Update Properties section in Maven pom.xml
  2. Add repositories and pluginRepository to Maven pom.xml
  3. Add Serenity, Serenity Rest Assured and JUnit dependencies to POM.xml
  4. Update Build Section of pom.xml
  5. Create the Test Code under src/java/test
  6. Create serenity.properties file in the root of the project
  7. Run the tests through commandline which generates Serenity Reports.

Project Structure

Step 1 – Update Properties section in Maven pom.xml

   <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <serenity.version>2.6.0</serenity.version>
    <serenity.maven.version>2.6.0</serenity.maven.version>
    <junit.version>4.13.2</junit.version>
    <rest.assured.version>4.4.0</rest.assured.version>
    <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
    <maven.failsafe.plugin.version>3.0.0-M5</maven.failsafe.plugin.version>
    <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

Step 2 – Add repositories and pluginRepository to Maven pom.xml

  <repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray</name>
            <url>https://jcenter.bintray.com</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray-plugins</name>
            <url>https://jcenter.bintray.com</url>
        </pluginRepository>
    </pluginRepositories>

Step 3 – Add Serenity, Serenity Cucumber, Serenity Rest Assured, Rest Assured and JUnit 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>      
        
    </dependencies>

Step 4 – Update 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>**/*.Test</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>

Step 5 – Create the Test Code under src/java/test

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

@Test
	public void verifyValidUser() {

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

		SerenityRest.restAssuredThat(response -> response.statusCode(200)
                    .body("data.id", equalTo(1))
				    .body("data.employee_salary", equalTo(320800))
                    .body("data.employee_name", equalTo("Tiger Nixon"))
                    .body("data.employee_age", equalTo(61)).and()
				    .body("message", equalTo("Successfully! Record has been fetched.")));

	}

	@Test
	public void verifyInvalidUser() {
		response = SerenityRest.given()
                         .contentType("application/json")
                         .header("Content-Type", "application/json")
				  .when()
                         .get(URL + 99999);
		
       SerenityRest.restAssuredThat(response -> response.statusCode(200)
                   .body("status", equalTo("success"))
				   .body("message", equalTo("Successfully! Record has been fetched.")));

	}

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:

public class EmployeeSteps {

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

	@Step
	public void sendValidUser(int id) {
		response = SerenityRest.given().contentType("application/json").header("Content-Type", "application/json")
				.when().get(URL + id);

	}

	@Step
	public void verifyStatusCode(int expectedStatusCode) {
		SerenityRest.restAssuredThat(response -> response.statusCode(expectedStatusCode));
	}

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

	@Step
	public void verifyName(String expectedName) {
		SerenityRest.restAssuredThat(response -> response.body("data.employee_name", equalTo(expectedName)));
	}

	@Step
	public void verifySalary(int expectedSalary) {
		SerenityRest.restAssuredThat(response -> response.body("data.employee_salary", equalTo(expectedSalary)));
	}

	@Step
	public void verifyAge(int expectedAge) {
		SerenityRest.restAssuredThat(response -> response.body("data.employee_age", equalTo(expectedAge)));
	}

	@Step
	public void verifyMessage(String expectedMessage) {
		SerenityRest.restAssuredThat(response -> response.body("message", equalTo(expectedMessage)));
	}

	@Step
	public void verifyBodyStatus(String expectedStatus) {
		SerenityRest.restAssuredThat(response -> response.body("status", equalTo(expectedStatus)));
	}

}

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

@RunWith(SerenityRunner.class)
public class EmployeesTest {

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

	@Steps
	EmployeeSteps employeeSteps;

	@Test
	public void verifyValidUser() {
		employeeSteps.sendValidUser(1);
		employeeSteps.verifyStatusCode(200);
		employeeSteps.verifyId(1);
		employeeSteps.verifyName("Tiger Nixon");
		employeeSteps.verifyAge(61);
		employeeSteps.verifySalary(320800);
		employeeSteps.verifyMessage("Successfully! Record has been fetched.");

	}

	@Test
	public void verifyInvalidUser() {
		employeeSteps.sendValidUser(9999);
		employeeSteps.verifyStatusCode(200);
		employeeSteps.verifyBodyStatus("success");
		employeeSteps.verifyMessage("Successfully! Record has been fetched.");

	}

}

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

In the console you should find printed messages for tests start. At the same time under 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!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s