NashTech Blog

API Testing with WireMock and Jenkins: Automating Your Testing Workflow

Table of Contents
API Testing with WireMock and Jenkins

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:
  1. The 'WireMockServer' and ‘WireMock’ classes are imported to create and configure the mock server.
  • WireMockServer Initialization:
  1. A 'WireMockServer' instance is created and started on port ‘8080‘.
  2. The server is configured to listen to the localhost at port ‘8080’.
  • Stub Definitions:
  1. '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.
  2. ‘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:
  1. @BeforeClass annotated method 'setup()' starts the mock server and defines stubs.
  2. '@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:
  1. The test 'testGetResource' sends a GET request to the '/api/resource' endpoint.
  2. It then asserts that the status code is '200' and that the response body contains the expected message "Hello, WireMock!".
  • POST Request Test:
  1. The test 'testCreateResource' sends a 'POST' request with a JSON body to the '/api/resource' endpoint.
  2. 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

  1. 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:

Picture of yaminimohandoss

yaminimohandoss

I am Software Tester with 4.6 Years of Experience both Manual and Automation Testing across various environments. My aspiration is to continuously enhance my expertise by learning new technologies and exploring diverse environments, thereby expanding my skill set and staying abreast of industry advancements.

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top