Update 2020-04-07: This article has been updated for Gatling 3.3.1 as described here.
This is the third part in a series of posts in which I will present a written version of a workshop I recently held on load testing with Gatling. The target audience of the workshop was Java developers without any previous knowledge of Gatling and this series of articles is not different in this area.
Since I myself like concrete examples, the workshop was based a number of examples. A project containing all the examples is available on GitHub.
Earlier articles in the series are: Part 1 and part 2.
Example 5 – Body, Headers and Parameters
In the fifth example we will look at two different ways to set HTTP headers on the requests sent, how to set a body when doing a HTTP POST and finally how to add parameters to the URL.
package se.ivankrizsan.gatling.simulations import io.gatling.core.Predef._ import io.gatling.core.body.Body import io.gatling.core.structure.ScenarioBuilder import io.gatling.http.Predef._ import io.gatling.http.protocol.HttpProtocolBuilder /** * Example Gatling load test that sends one HTTP POST requests to a URL. * The body of the POST request contains the string "Farty Towels!". * Two ways of passing HTTP headers are shown. * Two URL parameters, "login" and "password", are passed in the URL of the request. * Note that this simulation should fail, since a non-expected HTTP status code should be returned. * Run this simulation with: * mvn -Dgatling.simulation.name=HttpSimulation5 gatling:test * * @author Ivan Krizsan */ class HttpSimulation5 extends Simulation { val theHttpProtocolBuilder: HttpProtocolBuilder = http .baseUrl("https://computer-database.gatling.io") .acceptHeader("application/xml, text/html, text/plain, application/json, */*") .acceptCharsetHeader("UTF-8") .acceptEncodingHeader("gzip, deflate") val theCommonHeaders = Map( "Accept" -> "application/xml, text/html, text/plain, application/json, */*", "Accept-Encoding" -> "gzip, deflate") val theBody : Body = StringBody("Farty Towels!") val theScenarioBuilder: ScenarioBuilder = scenario("Scenario1") .exec( http("Login and Post Data") .post("/computers") .body(theBody) .headers(theCommonHeaders) .queryParam("login", "admin") .queryParam("password", "secret") ) setUp( theScenarioBuilder.inject(atOnceUsers(1)) ).protocols(theHttpProtocolBuilder) }
Note that:
- When creating the HTTP protocol builder object, three method calls are chained after the invocation of the baseUrl method.
Rows 24, 25 and 26 in the listing above. These methods set HTTP header values that are to be enclosed with requests sent by the load simulation.
The acceptHeader call specifies what will be enclosed with the Accept HTTP header, the acceptCharsetHeader what will be enclosed with the Accept-Charset HTTP header and the acceptEncodingHeader what will be enclosed with the Accept-Encoding HTTP header.
Setting HTTP headers this way will cause them to be enclosed with every request issued using the protocol builder. - On rows 28 to 30 there is Scala code that creates a map containing HTTP header values for the Accept and Accept-Encoding HTTP headers.
Using a map we can enclose a set of HTTP headers with a request, as can be seen on row 39. - There is a immutable variable named theBody of the type Body initialised with a StringBody object containing the string “Farty towels!”.
Body data may be included with POST requests from different types of sources. This example shows how to enclose string data in a StringBody object, but there are InputStreamBody, RawFileBody, ByteArrayBody and CompositeByteArrayBody that retrieves body data from an input stream, a file specified by a filepath, a single byte array or a list of byte arrays. - In the Scenario1 scenario we can see that the “Login and Post Data” request is a POST request to /computers relative to the base URL.
- Following the post method call, there is a call to the body method with the theBody object parameter.
The body method is used to specify the body that is to be included with the HTTP POST request. - Chained after the body method call is a call to the headers method taking the map in the variable theCommonHeaders as parameter.
As before, this is how to specify the HTTP headers for one single request. Using different maps, we can enclose a different set of headers for each of the request in a scenario if we so desire. It is also possible to set individual headers using the header method. - Finally on rows 40 and 41 there are two calls to the queryParam method.
This will cause two query parameters, “login” and “password”, to be added to the request URL with the values “admin” and “secret” respectively.
The resulting request URL will look like this: computer-database.gatling.io/computers?login=admin&password=secret
Run the simulation with the following terminal command:
mvn -Dgatling.simulation.name=HttpSimulation5 gatling:test
The result will be that the single request sent by the simulation fails:
---- Errors -------------------------------------------------------------------- > status.find.in(200,304,201,202,203,204,205,206,207,208,209), 1 (100.0%) but actually found 400
The reason for this is that POST requests to the URL in question are not allowed.
This concludes the third part of the introduction to load testing with Gatling. The fourth and final part can be found here.
Happy coding!