Introduction
It has been 4 years since the last major release of Gatling, version 2.0. In October 2018, the Gatling team announced that version 3.0 had been released as open source software. Several exciting new features were released as part of Gatling 3.0, and we will cover the highlights in this blog post. A lot of the internals of Gatling have also been tweaked and improved, to make the load testing tool more efficient than ever.
Migrating to Gatling 3.0
The process of migrating to Gatling 3.0 should be reasonably straightforward for most users. You will need to update the version number in your build tool (3.0.0 at the time of writing, check the Gatling Github for the latest), or download the latest ZIP file from the Gatling website .
Other than that, it might be necessary to rename a few method names or feeder paths in your scripts that have changed in Gatling 3.0, but this should be obvious in your IDE.
New Features
The new features we will be covering in this post are divided between Gatling Core and Gatling HTTP, the two major modules of the Gatling project.
Gatling Core New Features
Support for Closed Workload Model
When you come to create your load injection profile in Gatling (i.e. the number and rate of new users), there are now two profiles that can be adopted:
- Closed Systems - where the system can only physically support a certain load. Examples of this would be a call center where you only have a limited number of agents or a waiting room where users take a ticket and wait in a queue to be served once the capacity is full
- Open Systems - where the system will continue trying to serve new users arriving, even if already at 'peak' load. Most websites behave in this way.
Gatling previously only supported Open Systems workload models, but now supports closed models as well. The syntax for a closed load injection profile would look like this:
bash
setUp(
scn.inject(
constantConcurrentUsers(10) during (10 seconds),
rampConcurrentUsers(10) to (20) during (10 seconds)
))
Read more about the new closed workload model in Gatling here.
Batching CSV Reader to improve Performance
Currently CSV feeders are loaded eagerly to avoid file IO during the simulation, but if the CSV files are large this can cause memory issues. The CSV reader in Gatling now loads CSV files in small batches, which trades memory usage for some file IO when a new batch is read.
Support for Compressed Feeder Files
Gatling can now support compressed feeder files, and will unzip them on the fly during script execution. Useful if your CSV files are large and you need to save disk space. Example usage:
bash
feed(csv("foo.csv.zip").unzip)
New Loops - doWhile, doWhileDuring and asLongAsDuring
Three new types of looping have been added, to give you greater flexibility in designing your test scenarios. Read more about the various loops Gatling offers here.
Support for Java 9, 10, 11
Gatling now supports Java versions 9, 10 and 11. Previously only Java 8 was supported.
New readRecords method for reading feeder content
Allows you to reuse the built in Gatling feeders to view the records of a file. This new method was necessary because of the introduction of batched feeders - previous the 'records' field of RecordSeqFeederBuilder was public and could be called, but this is no longer the case.
An example of using the new readRecords method:
bash
val records: Seq[Map[String, Any]] = csv("myFile.csv").readRecords
Note that each readRecords call will read the underlying source (e.g. parsing the CSV file) - if the file is large this could cause performance degradation in your Gatling system.
Console Stats Summary Print Interval is now Configurable
Previously when running a Gatling test, the console would update every 5 seconds with the test summary. This is now configurable by editing the 'gatling.conf' file
Replace splitUsers load injection method with incrementUsersPerSec and incrementConcurrentUsers
Previously the splitUsers method was used to design capacity tests with different levels of load. These new methods allow you to more clearly define what each level will look like
Open workload example using incrementUsersPerSec:
bash
incrementUsersPerSec(numberOfUsersPerSec: Double)
.times(nbOfSteps: Int)
.eachLevelLasting(duration: Duration)
.startingFrom(usersPerSec: Double)
.separatedByRampsLasting(duration: Duration)
Closed workload example using incrementConcurrentUsers:
bash
incrementConcurrentUsers(users: Int)
.times(nbOfSteps: Int)
.eachLevelLasting(duration: Duration)
.startingFrom(users: Int)
.separatedByRampsLasting(duration: Duration)
- Read more about Meta DSL in Gatling here.
Gatling HTTP New Features
Support for SOCKS 4 and 5 proxies
Gatling now supports SOCKS version 4 and version 5 proxies. Example usage:
bash
.proxy(Proxy("172.31.76.106", 8080).socks4).proxy(Proxy("172.31.76.106", 8080).socks5)
Name inferred resource request names -
Inferred resource request names are by default defined from the full URL, which can produce many request names and make for confusing results reports. You can now define a strategy for naming those requests in reports. See Resource Inferring in Gatling for more details.
Support for Pebble Template Engine
The Pebble templating engine is now supported for crafting request bodies in Gatling. A template engine allows you to add logic to your document or JSON, by placing keywords which are interpreted and replaced when the simulation is run . Examples of using Pebble in a Gatling script:
bash
.body(PebbleStringBody("""{ "myContent": "{myDynamicValue}" }""")).asJson// myFileBody.json is a file that contains// { "myContent": "{myDynamicValue}" }.body(PebbleFileBody("myFileBody.json")).asJson
Read more about the Pebble templating engine in Gatling here.
Support for HTTP/2 & New HTTP Client
Gatling now has the option of supporting HTTP/2 . Note that your injectors must be running with Java 9+ if you implement this. To enable HTTP/2 in your Gatling script:
bash
val httpProtocol = http.enableHttp2
More info on the new HTTP client in Gatling here.
New WebSocket API
There is a new API that allows for WebSocket support in Gatling scripts - this replaces the previous workaround that was used in Gatling 2.0 to support WebSockets
New findRandomError Check Method
In addition to the find() method (used for assertion and extracting data) you can now return a random match with findRandom()
Customise Error Messages
You can use the new name() method for customizing the name of the check in the error message, in case of a check failure
Load Cookie Value into a Session
The new getCookieValue() method can be used to extract the value of a cookie into a Gatling session, e.g.
bash
exec(getCookieValue(CookieKey("name"))
Gatling now uses Insecure TrustManager by Default
The default behaviour in Gatling is now to trust all server certificates. The reasoning behind this is that Gatling is a load test tool, not a security tool, and most test environments use a broken TLS configuration anyway.
Validators for dealing with null
JSON users can now check if a value is null or not null. Previously this was cumbersome to implement and could result in scripts failing with null exceptions. Example usage:
bash
jsonPath("$.foo").isNull
jsonPath("$.foo").notNull
Conclusion
Gatling 3.0 has been a long time in the making, but the wait has been worth it. The Gatling team have taken what was already an incredibly efficient and intuitive load testing tool and made it even better.
Here at Flood, we support Gatling execution in the cloud and are extremely excited for this new, feature packed release. We already support Gatling 3.0 in production.
Learn more about Gatling
If you are new to Gatling and would like to learn more, the Gatling Fundamentals Video Training course is a great way to get started. The course assumes no prior knowledge of Gatling, and walks you through everything needed to get up and running with Gatling from scratch.