In the previous tutorial, I explained about Integration Testing of Springboot with Cucumber and TestNG. In this tutorial, I will explain the Testing of the Gradle SpringBoot Application with Serenity, Cucumber, and JUnit4.
Prerequisite:
Spring Boot 3.0.4 requires Java 17 and is compatible with and including Java 19. Spring Framework 6.0.6 or above is also required.
Explicit build support is provided for the following build tools:
- Maven – 3.5+
- Gradle – 7.x (7.5 or later) and 8.x
This framework consists of
- SpringBoot Starter Parent – 3.1.0
- Serenity – 3.6.12
- Serenity Cucumber – 3.6.12
- Serenity JUnit4 – 3.6.12
- Serenity Rest Assured – 3.6.12
- Spring
- Java 17
- Gradle – 7.6.1
What is SpringBoot Application?
Spring Boot is an open-source micro-framework that provides Java developers with a platform to get started with an auto-configurable production-grade Spring application.
- Comes with embedded HTTP servers like Tomcat or Jetty to test web applications.
- Adds many plugins that developers can use to work with embedded and in-memory databases easily. Spring allows you to easily connect with database and queue services like Oracle, PostgreSQL, MySQL, MongoDB, Redis, Solr, ElasticSearch, Rabbit MQ, and others.
What is RestController?
HTTP requests are handled by a controller in Spring’s approach to building RESTful web services. The @RestController annotation identifies these components, and the HelloController shown below (from src/main/java/com/example/springboot_demo/HelloController.java) handles GET requests for / and /qaautomation by returning a new instance of the Greeting class. Spring RestController takes care of mapping request data to the request-defined handles method.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping(path="/")
String hello() {
return "Hello World, Spring Boot!";
}
@GetMapping(path="/qaautomation")
String qaautomation() {
return "Hello QA Automation!";
}
}
Project Directory Structure

Implementation Steps
- Create a source folder – src/test/resources to create properties file
- Add SpringBootTest, Rest Assured, and JUnit4 dependencies to the project
- Create a feature file in src/test/resources
- Create the StepDefinition and Helper classes.
- Create a Serenity Runner class in the src/test/java directory
- Create an application.properties file in src/test/resources
- Create a serenity.properties at the root level of the project
- Run the tests from Command Line
- Serenity Report Generation
- Cucumber Report Generation
Step 1 – Create a source folder – src/test/resources to create test scenarios in the Feature file
Right-click on the test directory and select New->Directory and select resources (Maven Source Directories).

Step 2 – Add SpringBootTest, Rest Assured, and other dependencies to the project
We have added SpringBootTest, SpringBoot Web, Tomcat, Spring Web, Rest Assured, and JUnit4 dependencies to the build.gradle.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0-SNAPSHOT'
id 'io.spring.dependency-management' version '1.1.0'
id "net.serenity-bdd.serenity-gradle-plugin" version "3.6.7"
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
implementation 'org.springframework:spring-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'net.serenity-bdd:serenity-core:3.6.12'
testImplementation 'net.serenity-bdd:serenity-cucumber:3.6.12'
testImplementation 'net.serenity-bdd:serenity-rest-assured:3.6.12'
testImplementation 'net.serenity-bdd:serenity-spring:3.6.12'
testImplementation 'net.serenity-bdd:serenity-junit:3.6.12'
testImplementation 'org.junit.vintage:junit-vintage-engine'
}
tasks.named('test') {
useJUnit() {}
testLogging {
showStandardStreams = true
}
systemProperties System.getProperties()
}
gradle.startParameter.continueOnFailure = true
test.finalizedBy(aggregate)
Step 3 – Create a feature file in src/test/resources
Below is an example of a feature file that shows a sample test scenario. Feature file should end with .feature. It contains the test scenarios in the form of simple English using the terms Given, When, Then, And.
Feature: SpringBoot Request
@ReceiveCorrectResponse
Scenario Outline: Send a valid Request to get correct response
Given I send a request to the URL "<url>"
Then the response will return "<response>"
Examples:
| url | response |
| / | Hello World, Spring Boot! |
| /qaautomation | Hello QA Automation! |
Step 4 – Create the StepDefinition and Helper classes.
Below is the code of the StepDefinition and Helper class. These classes are created in the src/test/java directory.
- uses @SpringBootTest annotation which loads the actual application context.
- uses WebEnvironment.RANDOM_PORT to create and run the application at some random server port.
- @LocalServerPort gets the reference of the port where the server has started. It helps in building the actual request URIs to mimic real client interactions.
AbstractRestAssuredHelper
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import net.serenitybdd.rest.SerenityRest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractRestAssuredHelper {
private final static String BASE_URI = "http://localhost";
@LocalServerPort
private int port;
@Value("${server.servlet.context-path}")
private String basePath;
protected void configureRestAssured() {
RestAssured.baseURI = BASE_URI;
RestAssured.port = port;
RestAssured.basePath = basePath;
}
protected RequestSpecification getAnonymousRequest() {
configureRestAssured();
return SerenityRest.given();
}
}
This class sends the request and receives a response after performing the GET operation. Here, the validation of the response also takes place by asserting the expected and actual response
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.restassured.response.Response;
import net.serenitybdd.rest.SerenityRest;
import net.thucydides.core.annotations.Steps;
import org.junit.Assert;
public class SpringBootDemoDefinitions {
@Steps
AbstractRestAssuredHelper helper;
private Response response;
@Given("I send a request to the URL {string}")
public void iSendARequest(String endpoint) throws Exception {
response = helper.getAnonymousRequest()
.header("Content-Type", "application/json").when().get(endpoint);
}
@Then("the response will return {string}")
public void extractResponse(String Expected ) {
SerenityRest.restAssuredThat(response -> response.statusCode(200));
String Actual = response.asString();
System.out.println("Result :"+Actual);
Assert.assertEquals(Expected, Actual);
}
}
Step 5 – Create a Serenity Runner class in the src/test/java directory
We cannot run a Feature file on its own in cucumber-based framework. We need to create a Java class that will run the Feature File. It is the starting point for JUnit to start executing the tests. TestRunner class is created under src/test/java. When you run the tests with serenity, you use the CucumberWithSerenity test runner.
import org.junit.runner.RunWith;
import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;
@RunWith(CucumberWithSerenity.class)
@CucumberOptions(features = "src/test/resources/features", tags = "", glue = "com.example.Gradle_SpringBoot_Demo", publish = true)
public class SpringRunnerTests {
}
Step 6 – Create an application.properties file in src/test/resources
Application.properties is created under src/test/java.
spring.profiles.active=dev
server.port=9091
server.servlet.context-path=/demo
spring.profiles.active – property to specify which profiles are active. The default profile is always active.
server.port – By default, the embedded server starts on port 8080. Now the server will start on port 8090
server.servlet.context-path – the context path in Spring Boot can be changed by setting a property, server.servlet.context-path.
Step 7 – Create a serenity.properties at the root level of the project
serenity.project.name = Testing of Gradle SpringBoot Application with Serenity and JUnit4 Demo
Step 8 – Run the tests from Command Line
Run the tests from the command line by using the below command
gradle clean test
The output of the above program is

This image shows that the profile name is “dev”. Application is started on port – “54462” and the context path is “/demo”.
Step 9 – Serenity Report Generation
By default, the test report generated by Serenity is placed under target/site/serenity/index.html. Below is the sample Serenity Report.

Below is the sample Serenity Report.


Step 10 – Cucumber Report Generation
A Cucumber Report can be generated by adding publish=true in SpringRunnerTests as shown in the above example. Click on the link provided in the execution status.

Cucumber Report

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