Introduction to WireMock and Jenkins
Ensuring the dependability of your APIs is essential in today’s software development to provide a top-notch user experience. Early issue detection and code quality maintenance are two benefits of automated API testing. This blog will walk you through the process of automating API testing with WireMock and Jenkins, covering how to create and manage test cases, test data, and test reports.
What is WireMock?
A flexible library for stubbing and mocking web services is called WireMock. Without depending on the real APIs, you can establish a controlled testing environment by simulating different API behaviours. WireMock is an effective tool for API testing since it can mimic both positive and negative responses, network latency, and other real-world events.
What is Jenkins?
A well-liked open-source automation server called Jenkins is used to construct, implement, and automate several stages of your software development process. It facilitates continuous delivery (CD) and continuous integration (CI), which helps teams find and solve bugs faster, write better code, and deploy new software updates more quickly.
Setting Up WireMock
Let’s start by configuring WireMock to build a simulated server for our API testing. To get started, take these actions:
1. Add WireMock Dependency
If you are using Maven, add the following dependency to your `pom.xml `file:
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.31.0</version>
<scope>test</scope>
</dependency>
For Gradle, add this to your `build.gradle `file:
testImplementation 'com.github.tomakehurst:wiremock-jre8:2.31.0'
2. Create a WireMock Server
Create a WireMock server in your test class and define the stubs for the API endpoints you want to mock.
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
public class ApiTest {
private static WireMockServer wireMockServer;
@BeforeClass
public static void setup() {
wireMockServer = new WireMockServer(8080);
wireMockServer.start();
WireMock.configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody("{ \"message\": \"Hello, WireMock!\" }")));
stubFor(post(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withStatus(201)));
}
@AfterClass
public static void teardown() {
wireMockServer.stop();
}
@Test
public void testGetResource() {
// Your test code here
}
@Test
public void testCreateResource() {
// Your test code here
}
}
Explanation:
- Imports:
- The
'WireMockServer' and‘WireMock’ classes are imported to create and configure the mock server.
- WireMockServer Initialization:
- A
'WireMockServer'instance is created and started on port ‘8080‘. - The server is configured to listen to the localhost at port ‘8080’.
- Stub Definitions:
'stubFor(get(urlEqualTo("/api/resource"))...)': This creates a stub for a'GET'request to the'/api/resource'endpoint, which returns a JSON response with a message.- ‘stubFor(post(urlEqualTo(“/api/resource”))…)’: This creates a stub for a
'POST'request to the'/api/resource'endpoint, which returns a'201'status code.
- Setup and Teardown:
- ‘
@BeforeClass‘ annotated method'setup()'starts the mock server and defines stubs. '@AfterClass'annotated method'teardown()'stops the mock server after tests are run.
3. Write API Tests
With the mock server running, you can write tests to interact with the mocked API endpoints.
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ApiTest {
// Existing setup and teardown methods...
@Test
public void testGetResource() {
given().
when().
get("http://localhost:8080/api/resource").
then().
statusCode(200).
body("message", equalTo("Hello, WireMock!"));
}
@Test
public void testCreateResource() {
given().
body("{ \"name\": \"New Resource\" }").
when().
post("http://localhost:8080/api/resource").
then().
statusCode(201);
}
}
Explanation:
- GET Request Test:
- The test
'testGetResource'sends aGETrequest to the'/api/resource'endpoint. - It then asserts that the status code is
'200'and that the response body contains the expected message"Hello, WireMock!".
- POST Request Test:
- The test
'testCreateResource'sends a'POST'request with a JSON body to the'/api/resource'endpoint. - It asserts that the status code is
'201', indicating successful creation.
Integrating with Jenkins
Now that we have our API tests set up with WireMock, let’s integrate them into a Jenkins pipeline to automate the testing process.
1. Install Jenkins:
If you haven’t installed Jenkins, follow the https://phoenixnap.com/kb/install-jenkins-on-windows
2. Create a New Jenkins Pipeline:
Create a new pipeline job in Jenkins and configure it to use a Jenkinsfile.
3. Define the Jenkinsfile
Create a `Jenkinsfile` in your project repository to define your pipeline. Below is an example of a Jenkinsfile that sets up the environment, runs the tests, and archives the test results.
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git 'https://github.com/your-repo/your-project.git'
}
}
stage('Build') {
steps {
sh 'mvn clean install'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
}
post {
always {
cleanWs()
}
}
}
4. Run the Pipeline
Save the Jenkinsfile and run the pipeline. Jenkins will check out the project, build it, run the API tests with WireMock, and archive the test results.
Tips for Creating and Managing Test Cases, Test Data, and Test Reports
Creating Test Cases
1. Define Clear Objectives:
Each test case should have a clear objective, whether it’s to verify a specific response, test error handling, or simulate different API behaviors.
@Test
public void testGetResource() {
given().
when().
get("http://localhost:8080/api/resource").
then().
statusCode(200).
body("message", equalTo("Hello, WireMock!"));
}
2. Use Descriptive Names:
Name your test cases descriptively to easily identify their purpose.
@Test
public void shouldReturnHelloMessageWhenGetResource() {
given().
when().
get("http://localhost:8080/api/resource").
then().
statusCode(200).
body("message", equalTo("Hello, WireMock!"));
}
3. Keep Tests Independent:
Ensure each test case can run independently without relying on the results of other tests.
@Test
public void shouldReturnStatus201WhenCreatingResource() {
given().
body("{ \"name\": \"New Resource\" }").
when().
post("http://localhost:8080/api/resource").
then().
statusCode(201);
}
Managing Test Data
1. Use Mock Data:
Use WireMock to create mock data for your tests. This ensures consistency and control over the test environment.
@BeforeClass
public static void setup() {
wireMockServer = new WireMockServer(8080);
wireMockServer.start();
WireMock.configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody("{ \"message\": \"Hello, WireMock!\" }")));
stubFor(post(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withStatus(201)));
}
2.Separate Test Data:
Store test data separately from your test code. This allows for easier updates and maintenance.
@BeforeClass
public static void setup() {
wireMockServer = new WireMockServer(8080);
wireMockServer.start();
WireMock.configureFor("localhost", 8080);
String getResourceResponse = "{ \"message\": \"Hello, WireMock!\" }";
String createResourceRequest = "{ \"name\": \"New Resource\" }";
stubFor(get(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(getResourceResponse)));
stubFor(post(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withStatus(201)));
}
3. Version Control:
git add test/resources
git commit -m "Add mock data for API tests"
git push origin main
Generating Test Reports
- Automate Report Generation: Use Jenkins to automatically generate and archive test reports after each run.
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
2. Use JUnit Reports: Configure your tests to produce JUnit-compatible reports, which Jenkins can parse and display.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
3. Review and Analyze: Regularly review and analyze your test reports to identify trends, recurring issues, and areas for improvement.
Conclusion
Automating your API testing workflow with WireMock and Jenkins significantly improves the efficiency and reliability of your testing process. WireMock allows you to simulate various API behaviors, while Jenkins automates the testing pipeline, providing continuous feedback on code quality. By integrating these tools, you can ensure your APIs are robust and reliable, catching issues early in the development cycle.
Reference
For More Details Visit here: