JMeter DSL: How to Load Test from your code

Performance testing is crucial in ensuring the reliability and scalability of software systems. However, traditional approaches to performance testing often treat it as a separate phase, leading to delayed feedback and issues surfacing late in development. Continuous Performance Testing aims to address this by integrating performance tests into the development pipeline, providing early insights into system performance. This tutorial introduces JMeter DSL, a Java API that simplifies and streamlines JMeter test creation and execution.

What is JMeterDSL?

JMeterDSL is a powerful Java API designed to create and run JMeter tests. Unlike traditional JMeter scripting, it emphasizes a more programmer-friendly approach, enabling developers and testers to craft more maintainable, readable, and version-controlled test plans. Ideal for teams embracing CI/CD environments, this tool helps scale tests in a continuous workflow.

Setting up JMeterDSL

To get started, set up a Maven project and include the following dependencies in your pom.xml:

  <dependencies>
    <dependency>
      <groupId>us.abstracta.jmeter</groupId>
      <artifactId>jmeter-java-dsl</artifactId>
      <version>1.23.3</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.24.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

These dependencies will enable you to work with JMeterDSL using JUnit 5 for testing and AssertJ for assertions.

Recording Test Flow

Traditionally, JMeter, tests are recorded using various recorders or proxies. With JMeterDSL, recording flows is simplified. For instance, you can use Fiddler to manually perform operations on the system under test while capturing the requests. In the following section we will show how to create a simple test to assert the Response Time from a Web site.

Creating a Simple Test

Let’s craft a simple test for using as sandbox the Opencart website. This example illustrates key features while scripting a performance test:

@Test
public void testPerformance() throws IOException {
    TestPlanStats stats = testPlan(
        threadGroup(1, 1,
            httpSampler("http://opencart.abstracta.us/")
        )
    ).run();
    assertThat(stats.overall().sampleTimePercentile99()).isLessThan(Duration.ofSeconds(5));
}

This script initiates a single user executing a GET request to Opencart’s home page and asserts the 99th percentile response time.

JMeter Java DSL performance API

Adding Headers, Assertions, and Timers

To enhance the test, we can include request headers, assertions for response validation, timers for simulating user behaviors, and even extract variables from responses to reuse in subsequent requests.

This script makes a GET request to the JSONPlaceholder API’s /posts/1 endpoint. It adds headers like "User-Agent" and "Accept" to the request.

private final String apiUrl = "https://jsonplaceholder.typicode.com/posts/1";

    @Test
    public void testCloudServiceAPI() throws IOException {
        TestPlanStats stats = testPlan(
            threadGroup(1, 1,
                httpSampler(apiUrl)
                    .header("User-Agent", "JMeterDSL")
                    .header("Accept", "application/json")
            )
        ).run();

        // Asserting 99th percentile response time
        assertThat(stats.overall().sampleTimePercentile99()).isLessThan(Duration.ofSeconds(5));
    }

Then, the following Test sets a 5-second constant timer and runs an HTTP request, checking if the test duration surpasses the timer duration:

@Test
  public void testWithTimer() throws Exception {
    Duration timerDuration = Duration.ofSeconds(5);
    TestPlanStats stats = testPlan(
            threadGroup(1, 1,
                    constantTimer(timerDuration),
                    httpSampler("http://opencart.abstracta.us/")
            )
    ).run();
    assertThat(stats.duration()).isGreaterThan(timerDuration);
}

Testing the Response Content

When your application is under load, the Response Time can differ just like the Response Content. In the following example, we are asserting that the response contains the HTML Page Title we expect:

@Test
public void OpencartTest() throws IOException {
    TestPlanStats stats = testPlan(
            threadGroup(1, 1,
                    httpSampler("Enter Opencart website", "http://opencart.abstracta.us")
                            .children(
                                    responseAssertion().containsSubstrings("<title>Your Store</title>")
                            )
            )
    ).run();
    assertThat(stats.overall().samplesCount()).isEqualTo(1);
    assertThat(stats.overall().sampleTimePercentile99()).isLessThan(Duration.ofSeconds(5));
}

Logging Test Details

JMeter DSL, primarily captures request and response details along with associated metrics by producing JTL files. This functionality seamlessly integrates with the jmeter-java-dsl via the accessible jtlWriter, demonstrated in the following example:.

  @Test
  public void testPOSTPerformance() throws IOException {
    TestPlanStats stats = testPlan(
            threadGroup(2, 10,
                    httpSampler("http://my.service")
                            .post("{\"name\": \"test\"}", ContentType.APPLICATION_JSON)
            ),
            jtlWriter("target/jtls")
    ).run();
    assertThat(stats.overall().sampleTimePercentile99()).isLessThan(Duration.ofSeconds(5));
  }

Conclusion

JMeter DSL simplifies performance testing, making test scripts more maintainable and facilitating their integration into CI/CD pipelines. Whether you are new to performance testing or an experienced user, JMeterDSL presents a valuable option to streamline the creation, execution, and maintenance of performance tests. Try it out to witness the ease it brings to load testing in your projects!

Source code: https://github.com/fmarchioni/mastertheboss/tree/master/various/jmeter-java-dsl