This content originally appeared on Level Up Coding - Medium and was authored by Lucas Fernandes
Is your Application resilient?
A Hands-on Guide with Java, JUnit, and Advanced Features

The goal of a tester is not to find bugs, it’s to validate that the software meets the requirements — Rex Black
Introduction: Why Load Testing Matters?
Ensuring that an application performs well under load is crucial in modern software development. Performance bottlenecks, slow response times, and system crashes can lead to poor user experience and revenue loss. Load testing helps identify performance issues before they impact users, ensuring the system can handle expected traffic.
Among various load-testing tools, Gatling stands out for its efficiency, scalability, and developer-friendly DSL. In this article, we’ll explore Gatling, its benefits, and how to integrate it with Java and JUnit for effective load testing.
What is Gatling?
Gatling is a powerful open-source load-testing tool designed to simulate realistic user traffic on applications. Written in Scala, it provides a flexible DSL for defining test scenarios. Key advantages of Gatling include:
- Asynchronous & Non-blocking: Efficiently handles multiple virtual users with fewer resources.
- Detailed Reports: Generates comprehensive HTML reports with response times, percentiles, and failure rates.
- Extensible & Developer-Friendly: Integrates well with Java, Scala, and CI/CD pipelines.
- Supports HTTP, WebSockets, and JMS: Making it suitable for testing various types of applications.
Now, let’s dive into a practical example using Gatling with Java, JUnit, and advanced features.
For further information, check out documentation
Hands-on: Load Testing with Gatling, Java, and JUnit
1. Setting Up Gatling in a Java Project
Add the Gatling dependencies to your build.gradle.
plugins {
// others plugins
id 'io.gatling.gradle' version '3.12.0'
}
// other configurations
dependencies {
// others dependencies
testImplementation 'io.gatling:gatling-test-framework:3.12.0'
}
// other configurations
gatling {
gatlingVersion = '3.12.0'
jvmArgs = ['-server', '-Xms512M', '-Xmx512M']
systemProperties = ['file.encoding': 'UTF-8']
}
2. Creating Rest API Application to Test
For testing purposes, we created a simple Rest API with Spring Boot using Spring Data Rest.
For further information, check out documentation
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'br.com.ldf.medium.gatling'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
runtimeOnly 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
@NoArgsConstructor
@Setter
@Getter
@Entity
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String email;
Long age;
}
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends JpaRepository<UserEntity, Long> {
UserEntity findByName(String name);
UserEntity findByEmail(String email);
List<UserEntity> findByAge(Long age);
}
This simple setup provides the following API Rest:

3. Writing Load Tests
Create a new Gatling test class simulation:
GetAll Users Load Test:
public class GetAllUsersSimulation extends Simulation {
HttpProtocolBuilder httpProtocol = http
.baseUrl("http://localhost:8080") // Base URL of the Spring Boot application
.acceptHeader("application/json");
ScenarioBuilder scn = scenario("""
Load test simulation for users endpoint with 1000 users at once and ramp up to 1000 users during 10 seconds with assertions
""")
.exec(http("users_get_all")
.get("/users")
.check(status().is(200)));
{
setUp(
scn.injectOpen(
atOnceUsers(1000), // Simulate 1000 users at once
rampUsers(100).during(10) // Ramp up to 100 users during 10 seconds
)
)
.assertions(
global().responseTime().max().lt(1500), // Assert that the maximum response time is less than 1500ms
global().successfulRequests().percent().gt(95.0), // Assert that 95% of the requests are successful
forAll().failedRequests().count().lt(5L) // Assert that the number of failed requests is less than 5
)
.protocols(httpProtocol);
}
}
Post Users Load Test:
public class PostUsersSimulation extends Simulation {
HttpProtocolBuilder httpProtocol = http
.baseUrl("http://localhost:8080") // Base URL of the Spring Boot application
.acceptHeader("application/json");
ScenarioBuilder scn = scenario("""
Load test simulation for users endpoint with 1000 users at once and ramp up to 1000 users during 10 seconds with assertions
""")
.exec(http("users_post")
.post("/users")
.body(StringBody("""
{
"name": "John Doe",
"email": "johndoe@gmail.com",
"age": 30
}
"""))
.check(status().is(201)));
{
setUp(
scn.injectOpen(
atOnceUsers(1000), // Simulate 1000 users at once
rampUsers(100).during(10) // Ramp up to 100 users during 10 seconds
)
)
.assertions(
global().responseTime().max().lt(1500), // Assert that the maximum response time is less than 1500ms
global().successfulRequests().percent().gt(95.0), // Assert that 95% of the requests are successful
forAll().failedRequests().count().lt(5L) // Assert that the number of failed requests is less than 5
)
.protocols(httpProtocol);
}
}
4. Running Gatling Tests with JUnit
You can use the Gatling plugin task: gatlingRun
./gradlew gatlingRun
Terminal Output:

5. Generating Reports
Gatling provides the following report:
build/reports/gatling/{scenario-test}/index.html




6. Gatling Features With Synchronous API
6.1 Authentication (JWT Token) Handling: If your API requires authentication, you can dynamically fetch and use a JWT token.
ScenarioBuilder scn = CoreDsl.scenario("Authenticated Load Test")
.exec(http("Authenticate")
.post("/auth/login")
.body(StringBody("""
{
"username": "test",
"password": "pass"
}
"""))
.check(jsonPath("$.token").saveAs("authToken"))); // Save token
6.2 Request Chaining (Extracting Data from Response): Extract data from one request and use it in another.
ScenarioBuilder scn = scenario("Chained Requests")
.exec(http("Create User")
.post("/users")
.body(StringBody("{ \"name\": \"John Doe\", \"email\": \"john@example.com\" }"))
.asJson()
.check(jsonPath("$.id").saveAs("userId"))) // Save user ID
.pause(1)
.exec(http("Get Created User")
.get("/users/#{userId}") // Use extracted user ID
.check(status().is(200)));
6.3 Data-Driven Testing (CSV Feeder)
Simulate different users using data from a CSV file (src/test/resources/users.csv):
username,password
user1,pass1
user2,pass2
user3,pass3
FeederBuilder<String> csvFeeder = csv("users.csv").random();
ScenarioBuilder scn = scenario("Login with Multiple Users")
.feed(csvFeeder) // Use CSV data
.exec(http("Login Request")
.post("/auth/login")
.body(StringBody("""
{
"username": "#{username}",
"password": "#{password}"
}
"""))
.asJson()
.check(status().is(200)));
Next Steps
In this article, we covered the use of Gatling for synchronous REST APIs. However, I am already working on an exclusive article to discuss asynchronous messaging systems, such as Kafka, SQS, and RabbitMQ.
Stay tuned for new articles and updates!
Conclusion
As demonstrated in the article, we see how important it is to test performance and real-world usage scenarios. At the end of the day, your application will always be tested on performance, load, and how it behaves during usage spikes.
Do you rather let your application’s user test it, or do you?
Gatling is a powerful tool for load testing, offering asynchronous execution, easy integration with Java, and rich reporting. It provides a domain-specific language (DSL) that facilitates the creation of readable and maintainable test scenarios and comprehensive HTML reports that detail various performance metrics, aiding in the analysis and optimization of API performance.
By integrating Gatling into your testing strategy, you can proactively identify and address potential performance bottlenecks, ensuring your APIs are robust and responsive under varying load conditions. This proactive approach contributes to the development of high-quality, reliable applications that meet user expectations.
Thank you for making it this far and for your valuable time reading this article.
API Rest Load Testing with Gatling was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Lucas Fernandes

Lucas Fernandes | Sciencx (2025-03-07T01:30:19+00:00) API Rest Load Testing with Gatling. Retrieved from https://www.scien.cx/2025/03/07/api-rest-load-testing-with-gatling/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.