Scenario
This is the reference of the different components available to write scenarios with Gatling.
Bootstrapping
scenario
is the way to bootstrap a new scenario.
ScenarioBuilder scn = scenario("Scenario");
const scn = scenario("Scenario");
val scn = scenario("Scenario")
val scn = scenario("Scenario")
You can use any character in the name of the scenario except tabulations: \t.
Structure elements
All the components in this section can be either:
- attached to a scenario
- directly created, so they can be passed as parameters, stored in constants, etc
- attached to another component in this section
Exec
The exec
method is used to execute an action.
Actions are usually requests (HTTP, WebSocket, JMS, MQTT…) that will be sent during the simulation.
Any action that will be executed will be called with exec
.
For example, when using the Gatling HTTP module you would write the following line:
// attached to a scenario
scenario("Scenario")
.exec(http("Home").get("https://gatling.io"));
// directly created and stored in a reference
ChainBuilder chain = exec(http("Home").get("https://gatling.io"));
// executed sequentially
exec(
http("Home").get("https://gatling.io"),
http("Enterprise").get("https://gatling.io/enterprise")
);
// attached to another
exec(http("Home").get("https://gatling.io"))
.exec(http("Enterprise").get("https://gatling.io/enterprise"));
// attached to a scenario
scenario("Scenario")
.exec(http("Home").get("https://gatling.io"));
// directly created and stored in a reference
const chain = exec(http("Home").get("https://gatling.io"));
// executed sequentially
exec(
http("Home").get("https://gatling.io"),
http("Enterprise").get("https://gatling.io/enterprise")
);
// attached to another
exec(http("Home").get("https://gatling.io"))
.exec(http("Enterprise").get("https://gatling.io/enterprise"));
// attached to a scenario
scenario("Scenario")
.exec(http("Home").get("https://gatling.io"))
// directly created and stored in a reference
val chain = exec(http("Home").get("https://gatling.io"))
// executed sequentially
exec(
http("Home").get("https://gatling.io"),
http("Enterprise").get("https://gatling.io/enterprise")
)
// attached to another
exec(http("Home").get("https://gatling.io"))
.exec(http("Enterprise").get("https://gatling.io/enterprise"))
// attached to a scenario
scenario("Scenario")
.exec(http("Home").get("https://gatling.io"))
// directly created and stored in a reference
val chain = exec(http("Home").get("https://gatling.io"))
// executed sequentially
exec(
http("Home").get("https://gatling.io"),
http("Enterprise").get("https://gatling.io/enterprise")
)
// attached to another
exec(http("Home").get("https://gatling.io"))
.exec(http("Enterprise").get("https://gatling.io/enterprise"))
exec
can also be passed a Function.
This can be used for manual debugging or to edit the Session, e.g.:
exec(session -> {
// displays the content of the session in the console
// WARNING: DEBUGGING ONLY, NOT UNDER LOAD
// sysout is a slow blocking output,
// massively writing in here will freeze Gatling's engine
System.out.println(session);
// return the original session
return session;
});
exec(session ->
// return a new session instance
// with a new "foo" attribute whose value is "bar"
session.set("foo", "bar")
);
exec((session) => {
// displays the content of the session in the console
// WARNING: DEBUGGING ONLY, NOT UNDER LOAD
// sysout is a slow blocking output,
// massively writing in here will freeze Gatling's engine
console.log(session);
// return the original session
return session;
});
exec((session) =>
// return a new session instance
// with a new "foo" attribute whose value is "bar"
session.set("foo", "bar")
);
exec { session ->
// displays the content of the session in the console
// WARNING: DEBUGGING ONLY, NOT UNDER LOAD
// sysout is a slow blocking output,
// massively writing in here will freeze Gatling's engine
println(session)
// return the original session
session
}
exec { session ->
// return a new session instance
// with a new "foo" attribute whose value is "bar"
session.set("foo", "bar")
}
exec { session =>
// displays the content of the session in the console
// WARNING: DEBUGGING ONLY, NOT UNDER LOAD
// sysout is a slow blocking output,
// massively writing in here will freeze Gatling's engine
println(session)
// return the original session
session
}
exec { session =>
// return a new session instance
// with a new "foo" attribute whose value is "bar"
session.set("foo", "bar")
}
setUp
. In particular, they have no effect when used inside functions.exec(session -> {
// just creates a dangling component, doesn't produce any effect
http("Gatling").get("https://gatling.io");
return session;
});
exec((session) => {
// just creates a dangling component, doesn't produce any effect
http("Gatling").get("https://gatling.io");
return session;
});
exec { session ->
// just creates a dangling component, doesn't produce any effect
http("Gatling").get("https://gatling.io")
session
}
exec { session =>
// just creates a dangling component, doesn't produce any effect
http("Gatling").get("https://gatling.io")
session
}
Pause
pause
When a user sees a page he/she often reads what is shown before choosing to click on another link. To reproduce this behavior, the pause method is used.
There are several ways to use it.
Fixed pause takes a single parameter:
duration
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a function
// with a number of seconds
pause(10);
// with a java.time.Duration
pause(Duration.ofMillis(100));
// with a Gatling EL string resolving to a number of seconds or a java.time.Duration
pause("#{pause}");
// with a function that returns a java.time.Duration
pause(session -> Duration.ofMillis(100));
// with a number of seconds
pause(10);
// with a Duration
pause({ amount: 100, unit: "milliseconds" });
// with a Gatling EL string resolving to a number of seconds or a Duration
pause("#{pause}");
// with a function that returns a Duration
pause((session) => ({ amount: 100, unit: "milliseconds" }));
// with a number of seconds
pause(10)
// with a java.time.Duration
pause(Duration.ofMillis(100))
// with a Gatling EL string resolving to a number of seconds or a java.time.Duration
pause("#{pause}")
// with a function that returns a java.time.Duration
pause { session -> Duration.ofMillis(100) }
// with a number of seconds
pause(10)
// with a scala.concurrent.duration.FiniteDuration
pause(100.millis)
// with a Gatling EL string resolving to a number of seconds or a scala.concurrent.duration.FiniteDuration
pause("#{pause}")
// with a function that returns a scala.concurrent.duration.FiniteDuration
pause(session => 100.millis)
Uniform random pause takes 2 parameters:
min
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a functionmax
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a function
// with a number of seconds
pause(10, 20);
// with a java.time.Duration
pause(Duration.ofMillis(100), Duration.ofMillis(200));
// with a Gatling EL strings
pause("#{min}", "#{max}");
// with a function that returns a java.time.Duration
pause(session -> Duration.ofMillis(100), session -> Duration.ofMillis(200));
// with a number of seconds
pause(10, 20);
// with a Duration
pause({ amount: 100, unit: "milliseconds" }, { amount: 100, unit: "milliseconds" });
// with a Gatling EL strings
pause("#{min}", "#{max}");
// with a function that returns a Duration
pause((session) => ({ amount: 100, unit: "milliseconds" }), (session) => ({ amount: 100, unit: "milliseconds" }));
// with a number of seconds
pause(10, 20)
// with a java.time.Duration
pause(Duration.ofMillis(100), Duration.ofMillis(200))
// with a Gatling EL strings
pause("#{min}", "#{max}")
// with a function that returns a java.time.Duration
pause({ session -> Duration.ofMillis(100) }) { session -> Duration.ofMillis(200) }
// with a number of seconds
pause(10, 20)
// with a scala.concurrent.duration.FiniteDuration
pause(100.millis, 200.millis);
// with a Gatling EL strings
pause("#{min}", "#{max}")
// with a function that returns a scala.concurrent.duration.FiniteDuration
pause(session => 100.millis, session => 200.millis)
pace
You could want to control how frequently an action is executed, to target iterations per time type volumes.
Gatling supports a dedicated type of pause: pace
, which adjusts its wait time depending on the elapsed time since the virtual user last reached this action.
E.g.:
forever().on(
pace(5)
.exec(
// will be run every 5 seconds, irrespective of what pause time is used
pause(1, 4)
)
);
forever().on(
pace(5)
.exec(
// will be run every 5 seconds, irrespective of what pause time is used
pause(1, 4)
)
);
forever().on(
pace(5)
.exec(
// will be run every 5 seconds, irrespective of what pause time is used
pause(1, 4)
)
)
forever(
pace(5)
.exec(
// will be run every 5 seconds, irrespective of what pause time is used
pause(1, 4)
)
)
There are several ways to use it.
Fixed pace takes a single parameter:
duration
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a function
// with a number of seconds
pace(10);
// with a java.time.Duration
pace(Duration.ofMillis(100));
// with a Gatling EL string resolving to a number of seconds or a java.time.Duration
pace("#{pace}");
// with a function that returns a java.time.Duration
pace(session -> Duration.ofMillis(100));
// with a number of seconds
pace(10);
// with a Duration
pace({ amount: 100, unit: "milliseconds" });
// with a Gatling EL string resolving to a number of seconds or a Duration
pace("#{pace}");
// with a function that returns a Duration
pace((session) => ({ amount: 100, unit: "milliseconds" }));
// with a number of seconds
pace(10)
// with a java.time.Duration
pace(Duration.ofMillis(100))
// with a Gatling EL string resolving to a number of seconds or a java.time.Duration
pace("#{pace}")
// with a function that returns a java.time.Duration
pace { session -> Duration.ofMillis(100) }
// with a number of seconds
pace(10)
// with a scala.concurrent.duration.FiniteDuration
pace(100.millis)
// with a Gatling EL string resolving to a number of seconds or a scala.concurrent.duration.FiniteDuration
pace("#{pace}")
// with a function that returns a scala.concurrent.duration.FiniteDuration
pace(session => 100.millis)
Uniform random pace takes 2 parameters:
min
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a functionmax
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a function
// with a number of seconds
pace(10, 20);
// with a java.time.Duration
pace(Duration.ofMillis(100), Duration.ofMillis(200));
// with a Gatling EL strings
pace("#{min}", "#{max}");
// with a function that returns a java.time.Duration
pace(session -> Duration.ofMillis(100), session -> Duration.ofMillis(200));
// with a number of seconds
pace(10, 20);
// with a Duration
pace({ amount: 100, unit: "milliseconds" }, { amount: 100, unit: "milliseconds" });
// with a Gatling EL strings
pace("#{min}", "#{max}");
// with a function that returns a Duration
pace((session) => ({ amount: 100, unit: "milliseconds" }), (session) => ({ amount: 100, unit: "milliseconds" }));
// with a number of seconds
pace(10, 20)
// with a java.time.Duration
pace(Duration.ofMillis(100), Duration.ofMillis(200))
// with a Gatling EL strings
pace("#{min}", "#{max}")
// with a function that returns a java.time.Duration
pace({ session -> Duration.ofMillis(100) }) { session -> Duration.ofMillis(200) }
// with a number of seconds
pace(10, 20)
// with a java.time.Duration
pace(100.millis, 200.millis)
// with a Gatling EL strings
pace("#{min}", "#{max}")
// with a function that returns a scala.concurrent.duration.FiniteDuration
pace(session => 100.millis, session => 200.millis)
rendezVous
In some cases, you may want to run some requests, then pause users until all other users have reached a rendez-vous point.
It takes a single parameter:
users
: the number of users to wait before lifting the waiting point, an int
rendezVous(100);
rendezVous(100);
rendezVous(100)
rendezVous(100)
Loop statements
counterName
parameter to force the loop index attribute name, be careful to use it in a read-only way.
Otherwise, you might break the Gatling underlying component’s internal logic.repeat
Repeat the loop a specified amount of times.
It takes 2 parameters:
times
: the number of times to repeat the loop content, can be an int, a Gatling EL String or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0
// with an Int times
repeat(5).on(
http("name").get("/")
);
// with a Gatling EL string resolving an Int
repeat("#{times}").on(
http("name").get("/")
);
// with a function times
repeat(session -> 5).on(
http("name").get("/")
);
// with a counter name
repeat(5, "counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
repeat(5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with an Int times
repeat(5).on(
http("name").get("/")
);
// with a Gatling EL string resolving an Int
repeat("#{times}").on(
http("name").get("/")
);
// with a function times
repeat((session) => 5).on(
http("name").get("/")
);
// with a counter name
repeat(5, "counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
repeat(5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with an Int times
repeat(5).on(
http("name").get("/")
)
// with a Gatling EL string resolving an Int
repeat("#{times}").on(
http("name").get("/")
)
// with a function times
repeat { session -> 5 }.on(
http("name").get("/")
)
// with a counter name
repeat(5, "counter").on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
repeat(5).on(
http("name1").get("/"),
http("name2").get("/")
)
// with an Int times
repeat(5)(
http("name").get("/")
)
// with a Gatling EL string resolving an Int
repeat("#{times}")(
http("name").get("/")
)
// with a function times
repeat(session => 5)(
http("name").get("/")
)
// with a counter name
repeat(5, "counter")(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
repeat(5)(
http("name1").get("/"),
http("name2").get("/")
)
foreach
Repeat the loop for each element in the specified sequence.
It takes 3 parameters:
seq
: the list of elements to iterate over, can be a List, a Gatling EL String or a functionelementName
: the key to the current element in theSession
counterName
(optional): the key to store the loop counter in theSession
, starting at 0
// with a static List
foreach(List.of("elt1", "elt2"), "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a Gatling EL string
foreach("#{elts}", "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a function
foreach(session -> List.of("elt1", "elt2"), "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a counter name
foreach(List.of("elt1", "elt2"), "elt", "counter").on(
http("name").get("/?elt=#{elt}&counter=#{counter}")
);
// iterating over multiple actions sequentially
foreach(List.of("elt1", "elt2"), "elt").on(
http("name1").get("/?elt=#{elt}"),
http("name2").get("/?elt=#{elt}")
);
// with a static List
foreach(["elt1", "elt2"], "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a Gatling EL string
foreach("#{elts}", "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a function
foreach((session) => ["elt1", "elt2"], "elt").on(
http("name").get("/?elt=#{elt}")
);
// with a counter name
foreach(["elt1", "elt2"], "elt", "counter").on(
http("name").get("/?elt=#{elt}&counter=#{counter}")
);
// iterating over multiple actions sequentially
foreach(["elt1", "elt2"], "elt").on(
http("name1").get("/?elt=#{elt}"),
http("name2").get("/?elt=#{elt}")
);
// with a static List
foreach(listOf("elt1", "elt2"), "elt").on(
http("name").get("/?elt=#{elt}")
)
// with a Gatling EL string
foreach("#{elts}", "elt").on(
http("name").get("/?elt=#{elt}")
)
// with a function
foreach({ session -> listOf("elt1", "elt2") }, "elt").on(
http("name").get("/?elt=#{elt}")
)
// with a counter name
foreach(listOf("elt1", "elt2"), "elt", "counter").on(
http("name").get("/?elt=#{elt}&counter=#{counter}")
)
// iterating over multiple actions
foreach(listOf("elt1", "elt2"), "elt").on(
http("name1").get("/?elt=#{elt}"),
http("name2").get("/?elt=#{elt}")
)
// with a static Seq
foreach(Seq("elt1", "elt2"), "elt")(
http("name").get("/?elt=#{elt}")
)
// with a Gatling EL string
foreach("#{elts}", "elt")(
http("name").get("/?elt=#{elt}")
)
// with a function
foreach(session => Seq("elt1", "elt2"), "elt")(
http("name").get("/?elt=#{elt}")
)
// with a counter name
foreach(Seq("elt1", "elt2"), "elt", "counter")(
http("name").get("/?elt=#{elt}&counter=#{counter}")
)
// iterating over multiple actions
foreach(Seq("elt1", "elt2"), "elt")(
http("name1").get("/?elt=#{elt}"),
http("name2").get("/?elt=#{elt}")
)
during
Iterate over the loop during the specified amount of time.
It takes 3 parameters:
duration
: can be an Int for a duration in seconds, a duration, a Gatling EL String or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0exitASAP
(optional, default true): if true, the condition will be evaluated for each element inside the loop, possibly causing to exit the loop before reaching the end of the iteration.
// with a duration in seconds
during(5).on(
http("name").get("/")
);
// with a java.time.Duration
during(Duration.ofMinutes(10)).on(
http("name").get("/")
);
// with a Gatling EL string resolving a duration
during("#{times}").on(
http("name").get("/")
);
// with a function times
during(session -> Duration.ofMinutes(10)).on(
http("name").get("/")
);
// with a counter name
during(5, "counter").on(
http("name").get("/?counter=#{counter}")
);
// with exitASAP
during(5, "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
during(5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a duration in seconds
during(5).on(
http("name").get("/")
);
// with a Duration
during({ amount: 10, unit: "minutes" }).on(
http("name").get("/")
);
// with a Gatling EL string resolving a duration
during("#{times}").on(
http("name").get("/")
);
// with a function times
during((session) => ({ amount: 10, unit: "minutes" })).on(
http("name").get("/")
);
// with a counter name
during(5, "counter").on(
http("name").get("/?counter=#{counter}")
);
// with exitASAP
during(5, "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
during(5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a duration in seconds
during(5).on(
http("name").get("/")
)
// with a java.time.Duration
during(Duration.ofMinutes(10)).on(
http("name").get("/")
)
// with a Gatling EL string resolving a duration
during("#{times}").on(
http("name").get("/")
)
// with a function times
during { session -> Duration.ofMinutes(10) }.on(
http("name").get("/")
)
// with a counter name
during(5, "counter").on(
http("name").get("/?counter=#{counter}")
)
// with exitASAP
during(5, "counter", false).on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
during(5).on(
http("name1").get("/"),
http("name2").get("/")
)
// with a duration in seconds
during(5)(
http("name").get("/")
)
// with a java.time.Duration
during(10.minutes)(
http("name").get("/")
)
// with a Gatling EL string resolving a duration
during("#{times}")(
http("name").get("/")
)
// with a function times
during(session => 10.minutes)(
http("name").get("/")
)
// with a counter name
during(5, "counter")(
http("name").get("/?counter=#{counter}")
)
// with exitASAP
during(5, "counter", false)(
http("name").get("/?counter=#{counter}")
)
asLongAs
Iterate over the loop as long as the condition is satisfied.
It takes 3 parameters:
condition
: can be a boolean, a Gatling EL String resolving a boolean or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0exitASAP
(optional, default true): if true, the condition will be evaluated for each element inside the loop, possibly causing to exit the loop before reaching the end of the iteration.
// with a Gatling EL string resolving to a boolean
asLongAs("#{condition}").on(
http("name").get("/")
);
// with a function
asLongAs(session -> session.getBoolean("condition")).on(
http("name").get("/")
);
// with a counter name and exitASAP
asLongAs("#{condition}", "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
asLongAs("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
asLongAs("#{condition}").on(
http("name").get("/")
);
// with a function
asLongAs((session) => session.get("condition")).on(
http("name").get("/")
);
// with a counter name and exitASAP
asLongAs("#{condition}", "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
asLongAs("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
asLongAs("#{condition}").on(
http("name").get("/")
)
// with a function
asLongAs { session -> session.getBoolean("condition") }.on(
http("name").get("/")
)
// with a counter name and exitASAP
asLongAs("#{condition}", "counter", false).on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
asLongAs("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
)
// with a Gatling EL string resolving a boolean
asLongAs("#{condition}")(
http("name").get("/")
)
// with a function
asLongAs(session => session("condition").as[Boolean])(
http("name").get("/")
)
// with a counter name and exitASAP
asLongAs("#{condition}", "counter", false)(
http("name").get("/?counter=#{counter}")
)
doWhile
Similar to asLongAs
but the condition is evaluated after the loop.
It takes 2 parameters:
condition
can be a boolean, a Gatling EL String resolving a boolean or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0
// with a Gatling EL string resolving to a boolean
doWhile("#{condition}").on(
http("name").get("/")
);
// with a function
doWhile(session -> session.getBoolean("condition")).on(
http("name").get("/")
);
// with a counter name
doWhile("#{condition}", "counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions
doWhile("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
doWhile("#{condition}").on(
http("name").get("/")
);
// with a function
doWhile((session) => session.get("condition")).on(
http("name").get("/")
);
// with a counter name
doWhile("#{condition}", "counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions
doWhile("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
doWhile("#{condition}").on(
http("name").get("/")
)
// with a function
doWhile { session -> session.getBoolean("condition") }.on(
http("name").get("/")
)
// with a counter name
doWhile("#{condition}", "counter").on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
doWhile("#{condition}").on(
http("name1").get("/"),
http("name2").get("/")
)
// with a Gatling EL string resolving to a boolean
doWhile("#{condition}")(
http("name").get("/")
)
// with a function
doWhile(session => session("condition").as[Boolean])(
http("name").get("/")
)
// with a counter name
doWhile("#{condition}", "counter")(
http("name").get("/?counter=#{counter}")
)
asLongAsDuring
Iterate over the loop as long as the condition is satisfied and the duration hasn’t been reached.
It takes 4 parameters:
condition
can be a boolean, a Gatling EL String resolving a boolean or a functionduration
can be an Int for a duration in seconds, a duration, a Gatling EL String or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0exitASAP
(optional, default true). If true, the condition will be evaluated for each element inside the loop, possibly causing to exit the loop before reaching the end of the iteration.
// with a Gatling EL string resolving to a boolean and an int duration
asLongAsDuring("#{condition}", 5).on(
http("name").get("/")
);
// with a counter name and exitASAP
asLongAsDuring(session -> true, Duration.ofMinutes(10), "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions
asLongAsDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean and an int duration
asLongAsDuring("#{condition}", 5).on(
http("name").get("/")
);
// with a counter name and exitASAP
asLongAsDuring((session) => true, { amount: 10, unit: "minutes" }, "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions
asLongAsDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean and an int duration
asLongAsDuring("#{condition}", 5).on(
http("name").get("/")
)
// with a counter name and exitASAP
asLongAsDuring({ session -> true }, Duration.ofMinutes(10), "counter", false).on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
asLongAsDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
)
// with a Gatling EL string resolving to a boolean and an int duration
asLongAsDuring("#{condition}", 5)(
http("name").get("/")
)
// with a counter name and exitASAP
asLongAsDuring(session => true, 10.minutes, "counter", false)(
http("name").get("/?counter=#{counter}")
)
doWhileDuring
Similar to asLongAsDuring
but the condition is evaluated after the loop.
It takes 3 parameters:
condition
can be a boolean, a Gatling EL String resolving a boolean or a functionduration
can be an Int for a duration in seconds, a duration, a Gatling EL String or a functioncounterName
(optional): the key to store the loop counter in theSession
, starting at 0
// with a Gatling EL string resolving to a boolean and an int duration
doWhileDuring("#{condition}", 5).on(
http("name").get("/")
);
// with a counter name and exitASAP
doWhileDuring(session -> true, Duration.ofMinutes(10), "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
doWhileDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean and an int duration
doWhileDuring("#{condition}", 5).on(
http("name").get("/")
);
// with a counter name and exitASAP
doWhileDuring((session) => true, { amount: 10, unit: "minutes" }, "counter", false).on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
doWhileDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean and an int duration
doWhileDuring("#{condition}", 5).on(
http("name").get("/")
)
// with a counter name and exitASAP
doWhileDuring({ session -> true }, Duration.ofMinutes(10), "counter", false).on(
http("name").get("/?counter=#{counter}")
)
// iterating over multiple actions
doWhileDuring("#{condition}", 5).on(
http("name1").get("/"),
http("name2").get("/")
)
// with a Gatling EL string resolving to a boolean and an int duration
doWhileDuring("#{condition}", 5)(
http("name").get("/")
)
// with a counter name and exitASAP
doWhileDuring(session => true, 10.minutes, "counter", false)(
http("name").get("/?counter=#{counter}")
)
forever
Iterate over the loop content forever.
forever().on(
http("name").get("/")
);
// with a counter name
forever("counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
forever().on(
http("name1").get("/"),
http("name2").get("/")
);
forever().on(
http("name").get("/")
);
// with a counter name
forever("counter").on(
http("name").get("/?counter=#{counter}")
);
// iterating over multiple actions sequentially
forever().on(
http("name1").get("/"),
http("name2").get("/")
);
forever().on(
http("name").get("/")
)
// with a counter name
forever("counter").on(
http("name").get("/")
)
// iterating over multiple actions
forever().on(
http("name1").get("/"),
http("name2").get("/")
)
forever(
http("name").get("/")
)
// with a counter name
forever("counter")(
http("name").get("/?counter=#{counter}")
)
counterName is optional.
Conditional statements
Gatling’s DSL has conditional execution support.
doIf
Used to execute a specific chain of actions only when some condition is satisfied.
It takes one single parameter:
condition
can be a boolean, a Gatling EL String resolving a boolean or a function
// with a Gatling EL string resolving to a boolean
doIf("#{condition}").then(
http("name").get("/")
);
// with a function
doIf(session -> session.getBoolean("condition")).then(
http("name").get("/")
);
// executing multiple actions
doIf("#{condition}").then(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
doIf("#{condition}").then(
http("name").get("/")
);
// with a function
doIf((session) => session.get("condition")).then(
http("name").get("/")
);
// executing multiple actions
doIf("#{condition}").then(
http("name1").get("/"),
http("name2").get("/")
);
// with a Gatling EL string resolving to a boolean
doIf("#{condition}").then(
http("name").get("/")
)
// with a function
doIf { session -> session.getBoolean("condition") }.then(
http("name").get("/")
)
// executing multiple actions
doIf("#{condition}").then(
http("name1").get("/"),
http("name2").get("/")
)
// with a Gatling EL string resolving to a boolean
doIf("#{condition}")(
http("name").get("/")
)
// with a function
doIf(session => session("condition").as[Boolean])(
http("name").get("/")
)
doIfEquals
If your test condition is simply to compare two values, you can simply use doIfEquals
:
It takes 2 parameters:
actual
can be a static value, a Gatling EL String or a functionexpected
can be a static value, a Gatling EL String or a function
doIfEquals("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" is equal to "expectedValue"
http("name").get("/")
);
doIfEquals("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" is equal to "expectedValue"
http("name").get("/")
);
doIfEquals("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" is equal to "expectedValue"
http("name").get("/")
)
doIfEquals("#{actual}", "expectedValue")(
// executed if the session value stored in "actual" is equal to "expectedValue"
http("name").get("/")
)
doIfOrElse
Similar to doIf
, but with a fallback if the condition evaluates to false.
It takes one single parameter:
condition
can be a boolean, a Gatling EL String resolving a boolean or a function
doIfOrElse("#{condition}").then(
http("name").get("/")
).orElse(
http("else").get("/")
);
doIfOrElse("#{condition}").then(
http("name").get("/")
).orElse(
http("else").get("/")
);
doIfOrElse("#{condition}").then(
http("name").get("/")
).orElse(
http("else").get("/")
)
doIfOrElse("#{condition}")(
http("name").get("/")
)(
http("else").get("/")
)
doIfEqualsOrElse
Similar to doIfEquals
but with a fallback if the condition evaluates to false.
It takes 2 parameters:
actual
can be a static value, a Gatling EL String or a functionexpected
can be a static value, a Gatling EL String or a function
doIfEqualsOrElse("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" equals to "expectedValue"
http("name").get("/")
).orElse(
// executed if the session value stored in "actual" is not equal to "expectedValue"
http("else").get("/")
);
doIfEqualsOrElse("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" equals to "expectedValue"
http("name").get("/")
).orElse(
// executed if the session value stored in "actual" is not equal to "expectedValue"
http("else").get("/")
);
doIfEqualsOrElse("#{actual}", "expectedValue").then(
// executed if the session value stored in "actual" equals to "expectedValue"
http("name").get("/")
).orElse(
// executed if the session value stored in "actual" is not equal to "expectedValue"
http("else").get("/")
)
doIfEqualsOrElse("#{actual}", "expectedValue")(
// executed if the session value stored in "actual" equals to "expectedValue"
http("name").get("/")
)(
// executed if the session value stored in "actual" is not equal to "expectedValue"
http("else").get("/")
)
doSwitch
Add a switch in the chain. Every possible sub-chain is defined with a key. Switch is selected through the matching of a key with the evaluation of the passed expression. If no switch is selected, the switch is bypassed.
doSwitch("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
);
doSwitch("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
);
doSwitch("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
)
doSwitch("#{myKey}")( // beware: use parentheses, not curly braces!
"foo" -> exec(http("name1").get("/foo")),
"bar" -> http("name2").get("/bar")
)
doSwitchOrElse
Similar to doSwitch
, but with a fallback if no switch is selected.
doSwitchOrElse("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
);
doSwitchOrElse("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
);
doSwitchOrElse("#{myKey}").on(
onCase("foo").then(http("name1").get("/foo")),
onCase("bar").then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
)
doSwitchOrElse("#{myKey}")( // beware: use parentheses, not curly braces!
"foo" -> http("name1").get("/foo"),
"bar" -> http("name2").get("/bar")
)(
exec(http("name3").get("/baz"))
)
randomSwitch
randomSwitch
can be used to emulate simple Markov chains.
Simple means cyclic graphs are not currently supported.
randomSwitch().on(
percent(60.0).then(http("name1").get("/foo")),
percent(40.0).then(http("name2").get("/bar"))
);
randomSwitch().on(
percent(60.0).then(http("name1").get("/foo")),
percent(40.0).then(http("name2").get("/bar"))
);
randomSwitch().on(
percent(60.0).then(http("name1").get("/foo")),
percent(40.0).then(http("name2").get("/bar"))
)
randomSwitch( // beware: use parentheses, not curly braces!
60.0 -> http("name1").get("/foo"),
40.0 -> http("name2").get("/bar")
)
Percentages sum can’t exceed 100%. If sum is less than 100%, users that won’t fall into one of the chains will simply exit the switch and continue. Once users are done with the switch, they simply continue with the rest of the scenario.
randomSwitchOrElse
Similar to randomSwitch
, but with a fallback if no switch is selected (i.e.: random number exceeds percentages sum).
randomSwitchOrElse().on(
percent(60.0).then(http("name1").get("/foo")),
percent(20.0).then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
);
randomSwitchOrElse().on(
percent(60.0).then(http("name1").get("/foo")),
percent(20.0).then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
);
randomSwitchOrElse().on(
percent(60.0).then(http("name1").get("/foo")),
percent(20.0).then(http("name2").get("/bar"))
).orElse(
http("name3").get("/baz")
)
randomSwitchOrElse( // beware: use parentheses, not curly braces!
60.0 -> http("name1").get("/foo"),
20.0 -> http("name2").get("/bar")
)(
http("name3").get("/baz")
)
uniformRandomSwitch
Similar to randomSwitch
, but with an uniform distribution amongst chains.
uniformRandomSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
);
uniformRandomSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
);
uniformRandomSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
)
uniformRandomSwitch( // beware: use parentheses, not curly braces!
http("name1").get("/foo"),
http("name2").get("/bar")
)
roundRobinSwitch
Similar to randomSwitch
, but dispatch uses a round-robin strategy.
roundRobinSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
);
roundRobinSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
);
roundRobinSwitch().on(
http("name1").get("/foo"),
http("name2").get("/bar")
)
roundRobinSwitch( // beware: use parentheses, not curly braces!
http("name1").get("/foo"),
http("name2").get("/bar")
)
Errors handling
tryMax
Any error (a technical exception such as a timeout, or a failed check) in the wrapped chain would cause the virtual user to interrupt and start over from the beginning, up to a maximum number of times. All requests performed in failing iterations will be logged, including the failing one.
It takes 2 parameters:
times
: the maximum number of attempts, an intcounterName
(optional): the key to store the loop counter in theSession
, starting at 0
tryMax(5).on(
http("name").get("/")
);
// with a counter name
tryMax(5, "counter").on(
http("name").get("/")
);
tryMax(5).on(
http("name").get("/")
);
// with a counter name
tryMax(5, "counter").on(
http("name").get("/")
);
tryMax(5).on(
http("name").get("/")
)
// with a counter name
tryMax(5, "counter").on(
http("name").get("/")
)
tryMax(5)(
http("name").get("/"),
http("name").get("/")
)
// with a counter name
tryMax(5, "counter")(
http("name").get("/")
)
exitBlockOnFail
Similar to tryMax, but without retrying on failure.
exitBlockOnFail().on(
http("name").get("/")
);
exitBlockOnFail().on(
http("name").get("/")
);
exitBlockOnFail().on(
http("name").get("/")
)
exitBlockOnFail(
http("name").get("/")
)
exitHere
Make the user exit the scenario from this point.
exitHere();
exitHere();
exitHere()
exitHere
exitHereIf
Make the user exit the scenario from this point if the condition holds.
It takes one single parameter:
condition
: can be a boolean, a Gatling EL String resolving a boolean or a function
exitHereIf("#{myBoolean}");
exitHereIf(session -> true);
exitHereIf("#{myBoolean}");
exitHereIf((session) => true);
exitHereIf("#{myBoolean}")
exitHereIf { session -> true }
exitHereIf("#{condition}")
exitHereIf(session => true)
exitHereIfFailed
Make the user exit the scenario from this point if it previously had an error.
exitHereIfFailed();
exitHereIfFailed();
exitHereIfFailed()
exitHereIfFailed
stopLoadGenerator
and crashLoadGenerator
Make the user exit abruptly stop the load generator.
It takes one single parameter:
message
: can be a static String, a Gatling EL String resolving a String or a function, used to log a message
stopLoadGenerator("#{someErrorMessage}");
stopLoadGenerator(session -> "someErrorMessage");
crashLoadGenerator("#{someErrorMessage}");
crashLoadGenerator(session -> "someErrorMessage");
stopLoadGenerator("#{someErrorMessage}");
stopLoadGenerator((session) => "someErrorMessage");
crashLoadGenerator("#{someErrorMessage}");
crashLoadGenerator((session) => "someErrorMessage");
stopLoadGenerator("#{someErrorMessage}")
stopLoadGenerator { session -> "someErrorMessage"}
crashLoadGenerator("#{someErrorMessage}")
crashLoadGenerator { session -> "someErrorMessage"}
stopLoadGenerator("#{someErrorMessage}")
stopLoadGenerator(session => "someErrorMessage")
crashLoadGenerator("#{someErrorMessage}")
crashLoadGenerator(session => "someErrorMessage")
The crash
flavor causes Gatling to exit with a failure code.
stopLoadGeneratorIf
and crashLoadGeneratorIf
Make the user exit abruptly stop the load generator.
It takes 2 parameters:
message
: can be a static String, a Gatling EL String resolving a String or a function, used to log a messagecondition
: can be a boolean, a Gatling EL String resolving a boolean or a function
stopLoadGeneratorIf("#{someErrorMessage}", "#{condition}");
stopLoadGeneratorIf(session -> "someErrorMessage", session -> true);
crashLoadGeneratorIf("#{someErrorMessage}", "#{condition}");
crashLoadGeneratorIf(session -> "someErrorMessage", session -> true);
stopLoadGeneratorIf("#{someErrorMessage}", "#{condition}");
stopLoadGeneratorIf((session) => "someErrorMessage", (session) => true);
crashLoadGeneratorIf("#{someErrorMessage}", "#{condition}");
crashLoadGeneratorIf((session) => "someErrorMessage", (session) => true);
stopLoadGeneratorIf("#{someErrorMessage}", "#{condition}")
stopLoadGeneratorIf( { session -> "someErrorMessage"}, { session -> true })
crashLoadGeneratorIf("#{someErrorMessage}", "#{condition}")
crashLoadGeneratorIf( { session -> "someErrorMessage"}, { session -> true })
stopLoadGeneratorIf("#{someErrorMessage}", "#{condition}")
stopLoadGeneratorIf(session => "someErrorMessage", session => true)
crashLoadGeneratorIf("#{someErrorMessage}", "#{condition}")
crashLoadGeneratorIf(session => "someErrorMessage", session => true)
The crash
flavor causes Gatling to exit with a failure code.
Groups
Create a group of requests to model processes or requests in the same page. Groups can be nested.
group("foo").on(
exec(http("name").get("/"))
);
group("foo").on(
exec(http("name").get("/"))
);
group("foo").on(
exec(http("name").get("/"))
)
group("foo")(
exec(http("name").get("/"))
)