Back to blog
Jan 26, 2025
3 min read

Gatling tests as Spring Application

basic start of request processing framework in Spring Boot

Dynamic Performance Testing with Gatling, Spring and Java 17

Performance testing is crucial for ensuring application reliability under load. This guide demonstrates how to create dynamic performance test scenarios using Gatling, Spring Boot, and Java 17.

Project Setup

First, add the required dependencies to your pom.xml:

pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.gatling</groupId>
<artifactId>gatling-app</artifactId>
<version>3.9.5</version>
</dependency>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>3.9.5</version>
</dependency>
</dependencies>

Controller Implementation

Create a REST controller to handle test configurations:

PerformanceTestController.java
@RestController
@RequestMapping("/api/v1")
public class PerformanceTestController {
private final ScenarioService scenarioService;
@PostMapping("/start-by-payload")
public ResponseEntity<TestExecutionResponse> startTest(@RequestBody TestConfiguration config) {
return ResponseEntity.ok(scenarioService.executeTest(config));
}
}

Configuration Models

Define the data models using Java records:

TestConfiguration.java
public record TestConfiguration(
List<Scenario> scenarios,
GlobalConfig globalConfig
) {}
public record Scenario(
String testName,
String testDescription,
TestConfig testConfig,
Request request,
TestData data
) {}
public record TestConfig(
int numberOfUsers,
int rampUpDuration,
int holdDuration,
int maxResponseTime,
int thinkTime
) {}
public record Variable(
String name,
String type,
List<Object> values,
String strategy
) {}

Scenario Generation Service

Create a service to convert the configuration into Gatling scenarios:

ScenarioService.java
@Service
public class ScenarioService {
public TestExecutionResponse executeTest(TestConfiguration config) {
List<Simulation> simulations = config.scenarios().stream()
.map(this::createSimulation)
.collect(Collectors.toList());
return runSimulations(simulations, config.globalConfig());
}
private Simulation createSimulation(Scenario scenario) {
return ScenarioBuilder.builder()
.name(scenario.testName())
.inject(
rampUsers(scenario.testConfig().numberOfUsers())
.during(Duration.ofSeconds(scenario.testConfig().rampUpDuration()))
)
.protocols(httpProtocol(scenario.request()))
.exec(createRequest(scenario))
.build();
}
private HttpProtocolBuilder httpProtocol(Request request) {
return http.baseUrl(request.baseUrl())
.headers(request.headers())
.check(status().is(200))
.check(responseTimeInMillis().lte(request.maxResponseTime()));
}
private ChainBuilder createRequest(Scenario scenario) {
return exec(http(scenario.testName())
.request(scenario.request().method())
.url(scenario.request().endpoint())
.queryParams(createDynamicParams(scenario.data()))
.check(status().is(200)));
}
private Map<String, Object> createDynamicParams(TestData data) {
return data.variables().stream()
.collect(Collectors.toMap(
Variable::name,
this::resolveVariableValue
));
}
private Object resolveVariableValue(Variable variable) {
if ("random".equals(variable.strategy())) {
return variable.values().get(
ThreadLocalRandom.current().nextInt(variable.values().size())
);
}
return variable.values().get(0);
}
}

Running the Tests

To execute a test scenario:

  1. Send a POST request to /api/v1/start-by-payload with your test configuration
  2. The service converts the configuration into Gatling simulations
  3. Executes the simulations with specified parameters
  4. Generates reports based on globalConfig settings

Example curl command:

run-test.sh
curl -X POST http://localhost:8080/api/v1/start-by-payload \
-H "Content-Type: application/json" \
-d @test-config.json

Key Features

  1. Dynamic scenario configuration through JSON payloads
  2. Flexible variable strategies (random, sequential)
  3. Customizable load patterns (users, ramp-up, duration)
  4. Comprehensive reporting options
  5. Failure threshold configuration

Best Practices

  1. Always set appropriate timeouts and response time thresholds
  2. Use meaningful test names for better reporting
  3. Start with lower user counts and gradually increase
  4. Monitor system resources during test execution
  5. Review generated reports for performance bottlenecks

The combination of Gatling’s powerful DSL, Spring Boot’s configuration capabilities, and Java 17’s modern features provides a robust framework for performance testing. This approach allows teams to maintain test scenarios as code while providing flexibility through dynamic configuration.