RelationDigest

Monday, 4 July 2022

[New post] Integration Testing of Springboot with Cucumber and TestNG

Site logo image vibssingh posted: " HOME In this tutorial, I am going to build an automation framework to test Springboot application with Cucumber, Rest Assured and TestNG. What is Springboot? Spring Boot is an open-source micro framework maintained by a company called " QA Automation Expert

Integration Testing of Springboot with Cucumber and TestNG

vibssingh

Jul 4

HOME

In this tutorial, I am going to build an automation framework to test Springboot application with Cucumber, Rest Assured and TestNG.

What is Springboot?

Spring Boot is an open-source micro framework maintained by a company called Pivotal. It provides Java developers with a platform to get started with an auto configurable production-grade Spring application. With it, developers can get started quickly without losing time on preparing and configuring their Spring application.

What is Cucumber?

Cucumber is a software tool that supports behavior-driven development (BDD). Cucumber can be defined as a testing framework, driven by plain English. It serves as documentation, automated tests, and a development aid – all in one.

This framework consists of:

  1. Springboot – 2.5.2
  2. Cucumber – 7.3.4
  3. Java 11
  4. TestNG – 7.3.4
  5. Maven – 3.8.1
  6. RestAssured – 5.1.1

Steps to setup Cucumber Test Automation Framework for API Testing using Rest-Assured

  1. Add SpringbootTest, Rest-Assured, JUnit and Cucumber dependencies to the project
  2. Create a source folder src/test/resources and create a feature file under src/test/resources
  3. Create the Step Definition class or Glue Code for the Test Scenario under src/test/java directory
  4. Create a Cucumber Runner class under src/test/java directory
  5. Run the tests from Cucumber Test Runner
  6. Run the tests from Command Line
  7. Run the tests from TestNG
  8. Generation of TestNG Reports
  9. Cucumber Report Generation

Below is the structure of a SpringBoot application project

We need below files to create a SpringBoot Application.

SpringBootRestServiceApplication.java

The Spring Boot Application class generated with Spring Initializer. This class acts as the launching point for application.

 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  @SpringBootApplication public class SpringBootRestServiceApplication {      public static void main(String[] args) {          SpringApplication.run(SpringBootRestServiceApplication.class, args);     } } 

Student.java

This is JPA Entity for Student class

 import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size;  @Entity public class Student {     @Id     @GeneratedValue     private Long id;      @NotNull     @Size(min = 4, message = "Name should have atleast 4 characters")     private String name;      @NotBlank(message = "passportNumber is mandatory")     private String passportNumber;      public Student() {         super();     }      public Student(Long id, String name, String passportNumber) {         super();         this.id = id;         this.name = name;         this.passportNumber = passportNumber;     }      public Long getId() {         return id;     }      public void setId(Long id) {         this.id = id;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public String getPassportNumber() {         return passportNumber;     }      public void setPassportNumber(String passportNumber) {         this.passportNumber = passportNumber;     } } 

StudentRepository.java 

This is JPA Repository for Student. This is created using Spring Data JpaRepository.

 import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;  @Repository public interface StudentRepository extends JpaRepository<Student, Long>{  } 

StudentController.java

Spring Rest Controller exposing all services on the student resource.

 import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; import java.net.URI; import java.util.List; import java.util.Optional; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder;  @RestController public class StudentController {      @Autowired     private StudentRepository studentRepository;      @GetMapping("/students")     public List<Student> retrieveAllStudents() {         return studentRepository.findAll();     }      @GetMapping("/students/{id}")     public EntityModel<Student> retrieveStudent(@PathVariable long id) {         Optional<Student> student = studentRepository.findById(id);          if (!student.isPresent())             throw new StudentNotFoundException("id-" + id);          EntityModel<Student> resource = EntityModel.of(student.get());          WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllStudents());          resource.add(linkTo.withRel("all-students"));          return resource;     }      @PostMapping("/students")     public ResponseEntity<Object> createStudent(@Valid @RequestBody Student student) {         Student savedStudent = studentRepository.save(student);          URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")                 .buildAndExpand(savedStudent.getId()).toUri();          return ResponseEntity.created(location).build();      } } 

application.properties

Spring Boot automatically loads the application.properties whenever it starts up. You can de reference values from the property file in the java code through the environment.

 spring.jpa.defer-datasource-initialization=true 

data.sql 

Data is loaded from data.sql into Student table. Spring Boot would execute this script after the tables are created from the entities.

 insert into student values(10001,'Annie', 'E1234567'); insert into student values(20001,'John', 'A1234568'); insert into student values(30001,'David','C1232268'); insert into student values(40001,'Amy','D213458'); 

Test Automation Framework Implementation

Step 1 – Add SpringbootTest, Cucumber, Rest-Assured and TestNG dependencies to the project (Maven project)

  <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <rest-assured.version>5.1.1</rest-assured.version>         <cucumber.version>7.3.4</cucumber.version>     </properties>  <dependencies>                  <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <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>io.cucumber</groupId>             <artifactId>cucumber-java</artifactId>             <version>${cucumber.version}</version>         </dependency>          <dependency>             <groupId>io.cucumber</groupId>             <artifactId>cucumber-testng</artifactId>             <version>${cucumber.version}</version>             <scope>test</scope>         </dependency>          <dependency>             <groupId>io.cucumber</groupId>             <artifactId>cucumber-spring</artifactId>             <version>${cucumber.version}</version>             <scope>test</scope>         </dependency>  </dependencies> 

Step 2 – Create a source folder src/test/resources and create a feature file under src/test/resources

By default, the Maven project has src/test/java directory only. Create a new Source Folder under src/test with the name of resources. Create a folder name as Features within src/test/resources directory.

Create a feature file to test the Springboot application. Below is a sample feature file.

 Feature: Verify springboot application using Cucumber and TestNG    @ReceiveUserDetails   Scenario Outline: Send a valid Request to get user details     Given I send a request to the URL "/students" to get user details     Then The response will return status 200      And The response contains id <studentID> and names "<studentNames>" and passport_no "<studentPassportNo>"      Examples:       |studentID    |studentNames  |studentPassportNo|       |10001        |Annie         |E1234567         |       |20001        |John          |A1234568         |       |30001        |David         |C1232268         |       |40001        |Amy           |D213458          |              @CreateUser   Scenario: Send a valid Request to create a user      Given I send a request to the URL "/students" to create a user with name "Annie" and passportNo "E1234567"     Then The response will return status 201     And Resend the request to the URL "/students" and the response returned contains name "Annie" and passport_no "E1234567" 

Step 3 – Create the Step Definition class or Glue Code for the Test Scenario under src/test/java

The corresponding step definition file of the above feature file is shown below.

 import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; import org.json.JSONObject; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.spring.CucumberContextConfiguration; import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.ValidatableResponse; import io.restassured.specification.RequestSpecification;  @CucumberContextConfiguration @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class SpringbootDefinitions {  	private final static String BASE_URI = "http://localhost";  	@LocalServerPort 	private int port;  	private ValidatableResponse validatableResponse, validatableResponse1;  	private void configureRestAssured() { 		RestAssured.baseURI = BASE_URI; 		RestAssured.port = port; 	}  	protected RequestSpecification requestSpecification() { 		configureRestAssured(); 		return given(); 	}  	@Given("I send a request to the URL {string} to get user details") 	public void getStudentDetails(String endpoint) throws Throwable { 		validatableResponse = requestSpecification().contentType(ContentType.JSON).when().get(endpoint).then(); 		System.out.println("RESPONSE :" + validatableResponse.extract().asString()); 	}  	@Given("I send a request to the URL {string} to create a user with name {string} and passportNo {string}") 	public void createStudent(String endpoint, String studentName, String studentPassportNumber) throws Throwable {  		JSONObject student = new JSONObject(); 		student.put("name", studentName); 		student.put("passportNumber", studentPassportNumber);  		validatableResponse = requestSpecification().contentType(ContentType.JSON).body(student.toString()).when() 				.post(endpoint).then(); 		System.out.println("RESPONSE :" + validatableResponse.extract().asString()); 	}  	@Then("The response will return status {int}") 	public void verifyStatusCodeResponse(int status) { 		validatableResponse.assertThat().statusCode(equalTo(status));  	}  	@Then("The response contains id {int} and names {string} and passport_no {string}") 	public void verifyResponse(int id, String studentName, String passportNo) { 		validatableResponse.assertThat().body("id", hasItem(id)).body(containsString(studentName)) 				.body(containsString(passportNo));  	}  	@Then("Resend the request to the URL {string} and the response returned contains name {string} and passport_no {string}") 	public void verifyNewStudent(String endpoint, String studentName, String passportNo) {  		validatableResponse1 = requestSpecification().contentType(ContentType.JSON).when().get(endpoint).then(); 		System.out.println("RESPONSE :" + validatableResponse1.extract().asString()); 		validatableResponse1.assertThat().body(containsString(studentName)).body(containsString(passportNo));  	} }  

To make Cucumber aware of your test configuration you can annotate a configuration class on your glue path with @CucumberContextConfiguration and with one of the following annotations: @ContextConfiguration, @ContextHierarchy or @BootstrapWith.It is imported from:

 import io.cucumber.spring.CucumberContextConfiguration; 

As we are using SpringBoot, we are annotating configuration class with @SpringBootTest. It is imported from:

 import org.springframework.boot.test.context.SpringBootTest; 

By default, @SpringBootTest does not start the webEnvironment to refine further how your tests run. It has several options: MOCK(default), RANDOM_PORT, DEFINED_PORT, NONE.

RANDOM_PORT loads a WebServerApplicationContext and provides a real web environment. The embedded server is started and listens on a random port. LocalServerPort is imported from package:

 import org.springframework.boot.web.server.LocalServerPort; 

Step 4 – Create a Cucumber TestNG Runner class under src/test/java

A runner will help us to run the feature file and acts as an interlink between the feature file and StepDefinition Class. The TestRunner should be created within the directory src/test/java.

 import io.cucumber.testng.AbstractTestNGCucumberTests; import io.cucumber.testng.CucumberOptions;  @CucumberOptions(features = {"src/test/resources/Features"}, glue = {"com.example.demo.definitions"}) public class CucumberRunnerTests extends AbstractTestNGCucumberTests {  } 

The @CucumberOptions annotation is responsible for pointing to the right feature package, configuring the plugin for a better reporting of tests in the console output, and specifying the package where extra glue classes may be found. We use it to load configuration and classes that are shared between tests.

Step 5 – Run the tests from Cucumber Test Runner

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

In case you are using IntelliJ, select "Run CucumberRunnerTests".

SpringBootTest creates an application context containing all the objects we need for the Integration Testing It, starts the embedded server, creates a web environment, and then enables methods to do Integration testing.

Step 6 – Run the tests from Command Line

Use the below command to run the tests through command line.

 mvn clean test 

Step 7 – Run the tests from TestNG

Create a testng.xml in the project as shown below:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name = "Suite1">   <test name = "SpringBoot Cucumber TestNG Demo">     <classes>           <class name = "com.example.demo.runner.CucumberRunnerTests"/>      </classes>      </test> </suite>  

Step 8 - Generation of TestNG Reports

TestNG generates the various types of reports under test-output folder like emailable-report.html, index.html, testng-results.xml.

We are interested in the'emailable-report.html' report. Open "emailable-report.html", as this is an HTML report, and open it with the browser. The below image shows emailable-report.html.

TestNG also produce "index.html" report, and it resides under test-output folder. The below image shows index.html report.

Step 9 - Cucumber Report Generation

Add cucumber.properties under src/test/resources and add the below instruction in the file.

 cucumber.publish.enabled=true 

The link to the Cucumber Report is present in the execution status.

Below is the image of the Cucumber Report generated using Cucumber Service.

Complete Source Code:
Refer to GitHub for source code.

Congratulations!! We are able to built a test framework to test SpringBoot application using Cucumber, Rest Assured and TestNG.

Comment
Like
Tip icon image You can also reply to this email to leave a comment.

Unsubscribe to no longer receive posts from QA Automation Expert.
Change your email settings at manage subscriptions.

Trouble clicking? Copy and paste this URL into your browser:
http://qaautomation.expert/2022/07/04/integration-testing-of-springboot-with-cucumber-and-testng/

Powered by WordPress.com
Download on the App Store Get it on Google Play
at July 04, 2022
Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest

No comments:

Post a Comment

Newer Post Older Post Home
Subscribe to: Post Comments (Atom)

This Month’s FilmFreeway Festival Discount Codes – 50% off codes!

Submit to the top festivals in the world today. ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏...

  • Sunnycare Aged Care Week 10
    https://advanceinstitute.com.au/2024/04/24/sunnycare-aged-care-week-10/?page_id=...
  • [New post] weather
    barbaraturneywielandpoetess posted: " life on a rooftop can be short ; depends whether one looks down or up . ...
  • [New post] County-Military Installation Coexistence: Partnerships for Success
    Victo...

Search This Blog

  • Home

About Me

RelationDigest
View my complete profile

Report Abuse

Blog Archive

  • October 2025 (64)
  • September 2025 (53)
  • August 2025 (54)
  • July 2025 (59)
  • June 2025 (53)
  • May 2025 (47)
  • April 2025 (42)
  • March 2025 (30)
  • February 2025 (27)
  • January 2025 (30)
  • December 2024 (37)
  • November 2024 (31)
  • October 2024 (29)
  • September 2024 (28)
  • August 2024 (2729)
  • July 2024 (3249)
  • June 2024 (3152)
  • May 2024 (3259)
  • April 2024 (3151)
  • March 2024 (3258)
  • February 2024 (3046)
  • January 2024 (3258)
  • December 2023 (3270)
  • November 2023 (3183)
  • October 2023 (3243)
  • September 2023 (3151)
  • August 2023 (3241)
  • July 2023 (3237)
  • June 2023 (3135)
  • May 2023 (3212)
  • April 2023 (3093)
  • March 2023 (3187)
  • February 2023 (2865)
  • January 2023 (3209)
  • December 2022 (3229)
  • November 2022 (3079)
  • October 2022 (3086)
  • September 2022 (2791)
  • August 2022 (2964)
  • July 2022 (3157)
  • June 2022 (2925)
  • May 2022 (2893)
  • April 2022 (3049)
  • March 2022 (2919)
  • February 2022 (2104)
  • January 2022 (2284)
  • December 2021 (2481)
  • November 2021 (3146)
  • October 2021 (1048)
Powered by Blogger.