Advanced load testing tools such as Gatling can deal with virtual users, each one having its own data and maybe taking a distinct browsing path.
Some other tools implement those virtual users as threads. Gatling implements them as messages, which scales much better and can deal easily with thousands of concurrent users.
To represent users’ behaviors, testers will have to define scenarios which will be written as scripts given to Gatling.
These scenarios can be the result of measurements on the running application with analytic tools, or expected users behavior of a new application. In any case, the creation of these scenarios is the key to meaningful results of the load test.
A scenario represents a typical user behavior. It’s a workflow that virtual users will follow.
For example, a standard e-commerce application scenario could be:
Scenarios are represented as scripts in conjunction with a DSL (Domain Specific Language). This allows fast writing of scenarios and easy maintenance of existing scenarios.
Here is a simple example of a scenario:
scenario("Standard User") .exec(http("Access Github").get("https://github.com")) .pause(2, 3) .exec(http("Search for 'gatling'").get("https://github.com/search?q=gatling")) .pause(2)
As we can easily guess, this scenario:
Pauses are used to simulate user think time. When a real user clicks on a link, the page has to be loaded in their browser and they will, most likely, read it and then decide what to do next.
HTTP requests are actually sent to the application under test when a user clicks on a button or a link. Each HTTP Request is easy to grasp (excluding page resources):
For more information, check the Scenario reference section.
A simulation is a description of the load test. It describes how, possibly several, user populations will run: which scenario they will execute and how new virtual users will be injected.
Here is an example of simulation definition:
val stdUser = scenario("Standard User") // etc.. val admUser = scenario("Admin User") // etc.. val advUser = scenario("Advanced User") // etc.. setUp( stdUser.inject(atOnceUsers(2000)), admUser.inject(nothingFor(60 seconds), rampUsers(5) over (400 seconds)), advUser.inject(rampUsers(500) over (200 seconds)) )
For more information, check the Simulation Setup reference section.
Each virtual user is backed by a Session. Those Sessions are the actual messages that go down the scenario workflow. A Session is basically a state placeholder, where testers can inject or capture and store data.
For more information, check the Session reference section.
When the tested application offers the possibility to authenticate, tests should take this into consideration and use data to test log in, log out, actions allowed only for certain users, and so on.
Gatling doesn’t provide tools to generate this test data.
Feeders are a convenient API for testers to inject data from an external source into the virtual users’ sessions.
For more information, check the Feeders reference section.
Each time a request is sent to the server, a response is normally sent, by the server, back to Gatling.
Gatling is able to analyze this response with Checks.
A check is a response processor that captures some part of it and verifies that it meets some given condition(s). For example, when sending an HTTP request, you could expect a HTTP redirect; with a check, you can verify that the status of the response is actually a 30x code.
Checks can also be used to capture some elements and store them into the Session so that they can be reused later, for example to build the next request.
For more information, check the Checks reference section.
Assertions are used to define acceptance criteria on Gatling statistics (e.g. 99th percentile response time) that would make Gatling fail and return an error status code for the test as a whole.
For more information, check the Assertions reference section.