Every Gatling test is called a "Simulation." Think of it as the equivalent of a JMeter Test Plan. A simulation contains three things: an HTTP protocol configuration (like JMeter's HTTP Request Defaults), one or more scenarios (like JMeter's Thread Groups), and a setUp block that wires everything together (like JMeter's thread count and ramp-up settings). Let me show you the anatomy of a simulation with a real example.
package com.example;
import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;
import java.time.Duration;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;
public class BrowseSimulation extends Simulation {
// 1. HTTP Protocol Configuration
// Like JMeter's HTTP Request Defaults
HttpProtocolBuilder httpProtocol = http
.baseUrl("https://www.testerrank.com")
.acceptHeader("text/html,application/json")
.acceptLanguageHeader("en-US,en;q=0.9")
.userAgentHeader("Gatling/LoadTest");
// 2. Scenario Definition
// Like JMeter's Thread Group + HTTP Samplers
ScenarioBuilder browseProducts = scenario("Browse Products")
.exec(
http("Home Page")
.get("/")
.check(status().is(200))
)
.pause(Duration.ofSeconds(2), Duration.ofSeconds(4))
.exec(
http("Product List")
.get("/shopping")
.check(status().is(200))
)
.pause(Duration.ofSeconds(1), Duration.ofSeconds(3))
.exec(
http("Product Detail")
.get("/shopping/products/1")
.check(status().is(200))
);
// 3. setUp Block
// Wires scenario + injection profile + protocol
{
setUp(
browseProducts.injectOpen(
rampUsers(100).during(Duration.ofSeconds(30))
)
).protocols(httpProtocol)
.assertions(
global().responseTime().percentile(95.0).lt(2000),
global().successfulRequests().percent().gt(99.0)
);
}
}package com.example
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class BrowseSimulation extends Simulation {
// 1. HTTP Protocol
val httpProtocol = http
.baseUrl("https://www.testerrank.com")
.acceptHeader("text/html,application/json")
.acceptLanguageHeader("en-US,en;q=0.9")
.userAgentHeader("Gatling/LoadTest")
// 2. Scenario
val browseProducts = scenario("Browse Products")
.exec(
http("Home Page")
.get("/")
.check(status.is(200))
)
.pause(2, 4)
.exec(
http("Product List")
.get("/shopping")
.check(status.is(200))
)
.pause(1, 3)
.exec(
http("Product Detail")
.get("/shopping/products/1")
.check(status.is(200))
)
// 3. setUp
setUp(
browseProducts.inject(
rampUsers(100).during(30.seconds)
)
).protocols(httpProtocol)
.assertions(
global.responseTime.percentile(95).lt(2000),
global.successfulRequests.percent.gt(99.0)
)
}The HTTP Protocol is your global configuration. Every request in every scenario inherits these settings -- base URL, default headers, connection timeouts. You define it once. The Scenario defines what a virtual user does -- a sequence of HTTP requests with pauses between them. The setUp block is where you connect the dots: which scenario, how many users, what load pattern, which protocol.
| JMeter Component | Gatling Equivalent | Example |
|---|---|---|
| Test Plan | Simulation class | class MyTest extends Simulation |
| HTTP Request Defaults | http.baseUrl(...) | http.baseUrl("https://www.testerrank.com") |
| Thread Group | scenario("name") | scenario("Browse Products") |
| HTTP Sampler | http("name").get/post("url") | http("Home").get("/") |
| Constant Timer | pause(duration) | pause(2) |
| Uniform Random Timer | pause(min, max) | pause(2, 4) |
| Response Assertion | check(status().is(200)) | check(status().is(200)) |
| Thread Count + Ramp-up | inject(rampUsers(n).during(d)) | rampUsers(100).during(30) |
| CSV Data Set Config | csv("file").random | feed(csv("users.csv").random) |
| View Results Tree | HTML report (automatic) | Open target/gatling/results/index.html |
Q: Explain the structure of a Gatling simulation. What are the key components?
A: A Gatling simulation has three core components. First, the HTTP Protocol Configuration, which defines the base URL, default headers, and connection settings -- similar to JMeter's HTTP Request Defaults. Second, one or more Scenarios that define user behavior as a sequence of HTTP requests with pauses between them -- like JMeter's Thread Group with samplers. Third, the setUp block that wires everything together: it specifies which scenario to run, the injection profile (how many users, what pattern), which protocol to use, and global assertions for pass/fail criteria. The entire simulation is a single class that extends Simulation, written in Scala or Java. This makes it self-contained, version-controllable, and easy to review in pull requests.
Key Point: A Gatling simulation has three parts: HTTP protocol (base config), scenario (user behavior), and setUp (load pattern + assertions). Everything is code -- one class, one file, fully self-contained.
Key Point: Three parts: HTTP protocol config, scenario definition, setUp block -- all code, all in one class