Performance testing with Gatling
Measuring the performance of an application is critical to business expansion and growth. One of the ways to achieve this is through load and performance tests. Load Testing ensures that your application can perform as expected in production. Just because your application will pass a functional test, this does not mean that it can perform the same under a load. Load testing identifies where and when your application breaks, so you can fix the issue before shipping to production.
What is load testing?
Load testing is a mechanism which helps us to identify the performance bottleneck in a website and take corrective measures which brings in a positive user experience. Be it a micro-service, a REST service or a website, load testing can help to identify the culprit bringing down the performance of the application and give an indication of optimal resources required to run smoothly.
What factors influence the performance of a website?
When we have a visitor on a website his expectation is that the site loads quick enough without having to wait for a long time. This basically depends on the response time to load different contents of the web page. This response time depends on two factors:
- The time taken by the frontend browser to load and display elements on the web page, and
- The time taken by the backend server to give response to a request These affect the performance of the website.
When should you perform load testing?
Ideally we should periodically keep monitoring the performance of our website to ensure the performance does not degrade over time. Most suitably whenever a new service or an application is being developed its performance should be measured and it should be released to production only when it meets the performance numbers expected from the application and all the performance parameters are within predefined threshold values.
How load testing works?
Load testing is focused on heavy load simulation. A load generator creates virtual users by sending requests to a server. These requests are increased in number over a period of time and response time of the server is measured. From the metrics collected we get an idea about the performance of the system and the max load that the system can handle.
What is Gatling?
Gatling is a powerful open-source load testing tool. It has excellent support for http protocol which makes it very efficient to test the performance of any http server. It has expressive DSL that makes it possible to write scenarios that are easy to understand. Its underlying architecture is asynchronous which makes it possible to implement virtual users as messages rather than as dedicated threads hence making it possible to use system resources very efficiently and running thousands of concurrent users without any issue.
How to perform load testing with Gatling?
Writing a performance test is very similar to writing any other automation test. The test class in which we are going to define our performance test must extend Simulation class of Gatling. Simulation is the parent class your tests must extend so Gatling can launch them. We define our test class like so:
public class GatlingTest extends Simulation {
}
Now within this class we define the rest of the elements of the performance test. To test the performance of an application we need to build a scenario which represents the action that a user would perform on the website. So we create a scenario like below which is sending an http get request to the server:
scenario("Scenario")
.exec(http("Home").get("https://gatling.io"));
The exec method is used to execute an action. In this case it is sending an http get request.
Scenarios are usually built with a ScenarioBuilder.
ScenarioBuilder scn = scenario("Scenario").exec(http("Home").get("https://gatling.io"));
The next important class is HttpProtocolBuilder using which we define various elements of the http request that we are going to send for eg. the base url, user agent, accept headers etc. We define it like this:
HttpProtocolBuilder httpProtocol = http.baseUrl("https://gatling.io”)
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate”);
ScenarioBuilder and HttpProtocolBuilder are the main and necessary elements to get started with performance test. Once these are defined we use the setUp method. This is a mandatory piece in your Simulations. It is essential to call the setUp method exactly once in the constructor to register the test components. This has to be done like this:
setUp(
scn.injectOpen(atOnceUsers(1))
).protocols(httpProtocol);
Now the complete simulation looks like this:
public class GatlingTest extends Simulation {
ScenarioBuilder scn = scenario("Scenario").exec(http("Home").get("https://gatling.io"));
HttpProtocolBuilder httpProtocol = http.baseUrl("https://gatling.io")
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate");
setUp(
scn.injectOpen(atOnceUsers(1))
).protocols(httpProtocol);
}
This will inject 1 user into the scenario. They’re different injection profiles for different use cases:
- injectOpen: to specify the arrival rate of users with no control on number of concurrent users
- injectClosed: to specify and control concurrent number of users
Some examples of injectOpen:
scn.injectOpen(
nothingFor(4),
atOnceUsers(10),
rampUsers(10).during(5),
constantUsersPerSec(20).during(15)
)
Some examples of injectClosed:
scn.injectClosed(
constantConcurrentUsers(10).during(10),
rampConcurrentUsers(10).to(20).during(10)
)
We need to choose the right injection profile based on the website usage. Once the simulation is defined we can execute it in many ways. One of the ways is to use io.gatling.gradle plugin and then run the simulations from commandline using gradle:
gradle gatlingRun
The simulation will run and at the end a beautiful performance test report is generated.
Hope this helps in getting started with performance testing.