How to Test Spring Boot Project using ZeroCode?
Zerocode automated testing framework for a REST API project concept is getting seen via this tutorial by taking a sample spring boot maven project. Let us see the dependencies for Zerocode :
<dependency> <groupId>org.jsmart</groupId> <artifactId>zerocode-tdd</artifactId> <version>1.3.27</version> <scope>test</scope> </dependency>
Zerocode framework supports the following
- REST
- SOAP
- Security
- Load/Stress
- Database
- Apache Kafka
- GraphQL
In this tutorial let us see REST API testing.
Example Project
Project Structure:
pom.xml
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 >com.gfg.zerocode</ groupId > < artifactId >zerocode</ artifactId > < packaging >jar</ packaging > < version >1.0-SNAPSHOT</ version > < dependencies > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-web</ artifactId > < version >${spring.boot.version}</ version > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < version >${spring.boot.version}</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.jsmart</ groupId > < artifactId >zerocode-tdd</ artifactId > < version >${zerocode-tdd.version}</ version > < scope >test</ scope > </ dependency > </ dependencies > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > < configuration > < profiles > < profile >it</ profile > </ profiles > </ configuration > < executions > < execution > < id >pre-integration-test</ id > < goals > < goal >start</ goal > </ goals > < configuration > < skip >${skip.it}</ skip > </ configuration > </ execution > < execution > < id >post-integration-test</ id > < goals > < goal >stop</ goal > </ goals > < configuration > < skip >${skip.it}</ skip > </ configuration > </ execution > </ executions > </ plugin > < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-failsafe-plugin</ artifactId > < version >${maven-failsafe-plugin.version}</ version > < configuration > < skip >${skip.it}</ skip > </ configuration > < dependencies > < dependency > < groupId >org.apache.maven.surefire</ groupId > < artifactId >surefire-junit47</ artifactId > < version >${surefire-junit47.version}</ version > </ dependency > </ dependencies > < executions > < execution > < goals > < goal >integration-test</ goal > < goal >verify</ goal > </ goals > </ execution > </ executions > </ plugin > </ plugins > </ build > < properties > < maven-failsafe-plugin.version >3.0.0-M5</ maven-failsafe-plugin.version > < surefire-junit47.version >3.0.0-M5</ surefire-junit47.version > < maven.compiler.source >8</ maven.compiler.source > < maven.compiler.target >8</ maven.compiler.target > < spring.boot.version >2.4.2</ spring.boot.version > < skip.it >true</ skip.it > < zerocode-tdd.version >1.3.27</ zerocode-tdd.version > </ properties > </ project > |
To test REST API, let us create a sample spring boot application. Let us create the model class first
GeekUser.java
Java
public class GeekUser { private String id; private String firstName; private String lastName; private String departmentName; public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this .departmentName = departmentName; } public float getSalary() { return salary; } public void setSalary( float salary) { this .salary = salary; } private float salary; public String getId() { return id; } public void setId(String id) { this .id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this .firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this .lastName = lastName; } } |
GeekUserZerocodeApplication.java
Java
import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; @SpringBootApplication @RestController @RequestMapping ( "/api/users" ) public class GeekUserZerocodeApplication { private List<GeekUser> users = new ArrayList<>(); public static void main(String[] args) { SpringApplication.run(GeekUserZerocodeApplication. class , args); } @PostMapping public ResponseEntity create( @RequestBody GeekUser user) { if (!StringUtils.hasText(user.getFirstName())) { return new ResponseEntity( "firstName can't be empty!" , HttpStatus.BAD_REQUEST); } if (!StringUtils.hasText(user.getLastName())) { return new ResponseEntity( "lastName can't be empty!" , HttpStatus.BAD_REQUEST); } if (!StringUtils.hasText(user.getDepartmentName())) { return new ResponseEntity( "DeparmentName can't be empty!" , HttpStatus.BAD_REQUEST); } if (user.getSalary() < 0 ) { return new ResponseEntity( "Salary is not valid!" , HttpStatus.BAD_REQUEST); } user.setId(UUID.randomUUID() .toString()); users.add(user); return new ResponseEntity(user, HttpStatus.CREATED); } } |
We have to write a scenario to test the same
{ "scenarioName": "geek test user creation endpoint", "steps": [ // Array of JSON objects, as much we want we can store { "name": "geek_test_successful_creation", "url": "/api/users", // Relative URL "method": "POST", "request": { "body": { // We have to specify whole bean class parameter and its values "firstName": "Rachel", "lastName": "Green", "departmentName":"IT", "salary":100000.0 } }, "verify": { // expected part containing status and body "status": 201, // status code for a given HTTP call "body": { // Resultant body from the call "id": "$NOT.NULL", "firstName": "Rachel", "lastName": "Green", "departmentName":"IT", "salary":100000.0 } } } }
The above one is a success call that creates a user. Similarly, we can do for validation part as well
{ "name": "test_firstname_validation", "url": "/api/users", "method": "POST", "request": { "body": { "firstName": "", "lastName": "Bing", "departmentName":"IT", "salary":100000.0 } }, "assertions": { "status": 400, "rawBody": "firstName can't be empty!" } }, { "name": "test_lastname_validation", "url": "/api/users", "method": "POST", "request": { "body": { "firstName": "Monica", "lastName": "", "departmentName":"Chef", "salary":100000.0 } }, "assertions": { "status": 400, "rawBody": "lastName can't be empty!" } }, { "name": "test_departmentname_validation", "url": "/api/users", "method": "POST", "request": { "body": { "firstName": "Phoebe", "lastName": "Buffe", "departmentName":"", "salary":50000.0 } }, "assertions": { "status": 400, "rawBody": "DeparmentName can't be empty!" } }
We can combine everything together and keep it under the test/resources folder. Basically, it is a JSON file and combines all the entries that are getting tested. Now coming to the test file part
- @RunWith(ZeroCodeUnitRunner.class) – ZeroCodeUnitRunner, as it is responsible for it
- @TargetEnv – Provide the property file that is required for running the scenario
GeekUserEndpointIT.java
Java
import org.jsmart.zerocode.core.domain.Scenario; import org.jsmart.zerocode.core.domain.TargetEnv; import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner; import org.junit.Test; import org.junit.runner.RunWith; // Here in RunWith it has been specified // as ZeroCodeUnitRunner, as it is responsible @RunWith (ZeroCodeUnitRunner. class ) // @TargetEnv – this points to the property file // that will be used when our scenario runs @TargetEnv ( "rest_api.properties" ) public class GeekUserEndpointIT { @Test @Scenario ( "rest/geek_user_create_test.json" ) public void test_geekuser_creation_endpoint() { } } |
rest_api.properties
web.application.endpoint.host=http://localhost # In case of changes they need to be modified appropriately web.application.endpoint.port=8080 web.application.endpoint.context=
For the execution of tests, in pom.xml necessary dependencies are added
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M5</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>3.0.0-M5</version> </dependency> </dependencies> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin>
We can run the project in the command line by using
mvn verify -Dskip.it=false
Under the target folder of the directory, we can see multiple files that help to understand different layers of testing
Similarly whatever testing scenarios given are validated against Zerocode
Contact Us