Scenario
Learn how to execute requests, pause, loops, conditions, throttling and protocols
This is the reference of the different components available to write scenarios with Gatling.
Bootstrapping
scenario
is the way to bootstrap a new scenario.
scenario("My Scenario")
You can use any character in the name of the scenario except tabulations: \t.
Structure elements
Exec
The exec
method is used to execute an action.
Actions are usually requests (HTTP, LDAP, POP, IMAP, etc) 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:
scenario("My Scenario")
.exec(http("Get Homepage").get("http://github.com/gatling/gatling"))
exec
can also be passed an Expression function.
This can be used for manually debugging or editing the Session, e.g.:
exec { session =>
// displays the content of the session in the console (debugging only)
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")
}
Session
instead of Validation[Session]
in the above examples,
that’s thanks to an implicit conversion.ActionBuilder
(s) that have to be chained altogether and are only built once on startup.
The results is a workflow chain of Action
(s).
These builders don’t do anything by themselves, they don’t trigger any side effect, they are just definitions.
As a result, creating such DSL components at runtime in functions is completely meaningless.
If you want conditional paths in your execution flow, use the proper DSL components (doIf
, randomSwitch
, etc)exec { session =>
if (someSessionBasedCondition(session)) {
// just create a builder that is immediately discarded, hence doesn't do anything
// you should be using a doIf here
http("Get Homepage").get("http://github.com/gatling/gatling")
}
session
}
flattenMapIntoAttributes
is a built-in Session Expression as mentioned above.
It exposes the content of a Map into attributes, e.g.:
// assuming the Session contains an attribute named "theMap" whose content is :
// Map("foo" -> "bar", "baz" -> "qix")
exec(flattenMapIntoAttributes("${theMap}"))
// the Session contains 2 new attributes "foo" and "baz".
Pause
pause
When a user sees a page he/she often reads what is shown and then chooses to click on another link. To reproduce this behavior, the pause method is used.
There are several ways of using it:
- Fixed pause duration:
pause(duration: Duration)
pause(duration: String, unit: TimeUnit = TimeUnit.SECONDS)
pause(duration: Expression[Duration])
- Uniform random pause duration:
pause(min: Duration, max: Duration)
pause(min: String, max: String, unit: TimeUnit)
pause(min: Expression[Duration], max: Expression[Duration])
pace
If you want to control how frequently an action is executed, to target iterations per hour type volumes.
Gatling support a dedicated type of pause: pace
, which adjusts its wait time depending on how long the chained action took.
E.g.:
forever(
pace(5 seconds)
.exec(
pause(1 second, 4 seconds) // Will be run every 5 seconds, irrespective of what pause time is used
)
)
There are several ways of using it:
- Fixed pace duration:
pace(duration: Duration)
pace(duration: String, unit: TimeUnit = TimeUnit.SECONDS)
pace(duration: Expression[Duration])
- Uniform random pace duration:
pace(min: Duration, max: Duration)
pace(min: String, max: String, unit: TimeUnit)
pace(min: Expression[Duration], max: Expression[Duration])
rendezVous
In some cases, you may want to run some requests, then pause users until all other users have reached a rendez-vous point.
For this purpose Gatling has the rendezVous(users: Int)
method which takes the number of users to wait.
Loop statements
counterName
parameter to force loop index attribute name, be careful to only use it in a read-only way.
Otherwise, you might break Gatling underlying component’s internal logic.repeat
Repeat the loop a specified amount of times.
repeat(times, counterName) {
myChain
}
times can be an Int, an EL string pointing to an Int Session attribute, or an Expression[Int]
.
counterName is optional and can be used to force the name of the loop counter. Current value can be retrieved on the Session as an attribute with a counterName name.
repeat(20) { myChain } // will loop on myChain 20 times
repeat("${myKey}") { myChain } // will loop on myChain (Int value of the Session attribute myKey) times
repeat(session => session("foo").as[Int] /* or anything that returns an Int*/ ) { myChain }
foreach
Repeat the loop for each element in the specified sequence.
foreach(sequenceName, elementName, counterName) {
myChain
}
sequenceName can be a sequence, an EL string pointing to a Seq[Any]
Session attribute, or an Expression[Seq[Any]]
elementName is a the name of the Session attribute that will hold the current element.
counterName is optional.
during
Iterate over the loop during the specified amount of time.
during(duration, counterName, exitASAP) {
myChain
}
duration can be an Int for a duration in seconds, or a duration expressed like 500 milliseconds.
counterName is optional.
exitASAP is optional and defaults to true. If true, the condition will be evaluated for each element inside the loop, possibly causing to exit before reaching the end of the iteration.
asLongAs
Iterate over the loop as long as the condition is satisfied.
asLongAs(condition, counterName, exitASAP) {
myChain
}
condition is a session function that returns a boolean.
counterName is optional.
exitASAP is optional and defaults to false. If true, the condition will be evaluated for each element inside the loop, possibly causing to exit before reaching the end of the iteration.
doWhile
Similar to asLongAs
but the condition is evaluated after the loop.
doWhile(condition, counterName) {
myChain
}
condition is a session function that returns a boolean.
counterName is optional.
asLongAsDuring
Iterate over the loop as long as the condition is satisfied and the duration hasn’t been reached.
asLongAsDuring(condition, duration, counterName) {
myChain
}
condition is a session function that returns a boolean.
duration can be an Int for a duration in seconds, or a duration expressed like 500 milliseconds.
counterName is optional.
doWhileDuring
Similar to asLongAsDuring
but the condition is evaluated after the loop.
doWhileDuring(condition, duration, counterName) {
myChain
}
condition is a session function that returns a boolean.
duration can be an Int for a duration in seconds, or a duration expressed like 500 milliseconds.
counterName is optional.
forever
Iterate over the loop forever.
forever(counterName) {
myChain
}
counterName is optional.
Conditional statements
doIf
Gatling’s DSL has conditional execution support.
If you want to execute a specific chain of actions only when some condition is satisfied, you can do so using the doIf
method.
doIf("${myBoolean}") {
// executed if the session value stored in "myBoolean" is true
exec(http("...").get("..."))
}
If you want to test complex conditions, you’ll have to pass an Expression[Boolean]
:
doIf(session => session("myKey").as[String].startsWith("admin")) {
// executed if the session value stored in "myKey" starts with "admin"
exec(http("if true").get("..."))
}
doIfEquals
Îf your test condition is simply to compare two values, you can simply use doIfEquals
:
doIfEquals("${actualValue}", "expectedValue") {
// executed if the session value stored in "actualValue" is equal to "expectedValue"
exec(http("...").get("..."))
}
doIfOrElse
Similar to doIf
, but with a fallback if the condition evaluates to false.
doIfOrElse(session => session("myKey").as[String].startsWith("admin")) {
// executed if the session value stored in "myKey" starts with "admin"
exec(http("if true").get("..."))
} {
// executed if the session value stored in "myKey" does not start with "admin"
exec(http("if false").get("..."))
}
doIfOrElse
only takes an Expression[Boolean]
, not the key/value signature.doIfEqualsOrElse
Similar to doIfEquals
but with a fallback if the condition evaluates to false.
doIfEqualsOrElse(session => session("actualValue").as[String], "expectedValue") {
// executed if the session value stored in "actualValue" equals to "expectedValue"
exec(http("if true").get("..."))
} {
// executed if the session value stored in "actualValue" is not equal to "expectedValue"
exec(http("if false").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}")( // beware: use parentheses, not curly braces!
key1 -> chain1,
key2 -> chain2
)
doSwitchOrElse
Similar to doSwitch
, but with a fallback if no switch is selected.
doSwitchOrElse("${myKey}")( // beware: use parentheses, not curly braces!
key1 -> chain1,
key2 -> chain2
)(
myFallbackChain
)
randomSwitch
randomSwitch
can be used to emulate simple Markov chains.
Simple means cyclic graphs are not currently supported.
randomSwitch( // beware: use parentheses, not curly braces!
percentage1 -> chain1,
percentage2 -> chain2
)
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( // beware: use parentheses, not curly braces!
percentage1 -> chain1,
percentage2 -> chain2
) {
myFallbackChain
}
uniformRandomSwitch
Similar to randomSwitch
, but with an uniform distribution amongst chains.
uniformRandomSwitch( // beware: use parentheses, not curly braces!
chain1,
chain2
)
roundRobinSwitch
Similar to randomSwitch
, but dispatch uses a round-robin strategy.
roundRobinSwitch( // beware: use parentheses, not curly braces!
chain1,
chain2
)
Errors handling
tryMax
tryMax(times, counterName) {
myChain
}
myChain is expected to succeed as a whole. If an error happens (a technical exception such as a timeout, or a failed check), the user will bypass the rest of the chain and start over from the beginning.
times is the maximum number of attempts.
counterName is optional.
exitBlockOnFail
exitBlockOnFail {
myChain
}
Quite similar to tryMax, but without looping on failure.
exitHere
If
exitHere
Make the user exit the scenario from this point.
exitHereIf
exitHere
Make the user exit the scenario from this point if the condition holds.
Condition parameter is an Expression[Boolean]
.
exitHereIfFailed
exitHereIfFailed
Make the user exit the scenario from this point if it previously had an error.
Groups definition
group(groupName) {
myChain
}
Create group of requests to model process or requests in a same page. Groups can be nested.
Protocol definition
You can configure protocols at scenario level with protocols
method:
scn.inject(atOnceUsers(5)).protocols(httpProtocol)
See the dedicated section for http protocol definition here.
Pause definition
You can configure pause definition at scenario level, see here for more information.
Throttling
You can also configure throttling at scenario level with throttle
method.
This way, you can configure different throttling profiles for different scenarios running in the same simulation.
scn.inject(rampUsers(500) during (10 minutes)).throttle(reachRps(100) in (10 seconds), holdFor(10 minutes))
For further information see the dedicated section here.