Locust Load Testing | Getting started

Tejendra Pal Singh
7 min readFeb 10, 2022

--

Hello everyone, in this article, I will be giving you all a general overview of the locust load testing tool. what is it? how to use it?. At trell, we are using this tool for the performance testing of our APIs. I will be showing you all this by writing a load test file for a public API. After reading this article, you all will have a good understanding of the tool and can start writing test files for your APIs.

Why Load Test?

I think we should care
Load testing is important because:

  1. We can simulate real-world usage scenarios.
  2. we can check the performance of the software at the time of peak load.
  3. We can identify the bottlenecks and correct them in time.

What is Load Testing?

According to the Guru99.com

Load Testing is a non-functional software testing process in which the performance of software application is tested under a specific expected load. It determines how the software application behaves while being accessed by multiple users simultaneously. The goal of Load Testing is to improve performance bottlenecks and to ensure stability and smooth functioning of software application before deployment

In simple words, Load testing is a way to get an idea of how your application will behave when accessed by multiple users at the same time.

Locust Load testing is a free open source load testing tool that can be used for exactly this purpose. All you have to do is to make a python script defining the behavior of your users and test cases, and then just run the script using locust localhost server’s UI, and after the load testing you will get detailed statistics along with a chart and numbers to analyze the performance of your application

Installing locust

Requirements

  1. Python ≥ version 3.x

2. After installing the python, just run the following command

3. Now run this command to verify the installation

What is Locustfile?

There is something called a locustfile which is a simple python script in which you will write your load test code, name it locustfile.py

Running Load Test

I will demonstrate how to write a locust file in the latter part of this article but suppose you have written your locustfile and now want to run it. Follow these steps;

  1. Navigate to the directory where your locustfile.py is located, and run the following command locust
  2. After that, go to your browser and open localhost:8089 , you will get a UI like this

Here enter the following details
i. Number of users: How many concurrent users do you want to simulate
ii. Spawn Rate: At which rate the users should be spawn, suppose you have selected 50 concurrent users, and spawn rate is 2, locust will firstly start from 0 users and each second will increase users by 2 until it reaches 50 users
iii. Host: Simply the host, like www.test.com

3. Now click on the start swarming, and you will see a dashboard like this
Here you can see different real-time statistics like RPS, p90, failures, charts, etc for every task/URL you are trying to load test

Writing a locustfile

Writing a locust file is simply writing a normal python file using some additional packages from the locust module. I am demonstrating by using reqres.in API for testing purposes. I will be breaking down a locustfile to give an idea.
I will only break down the locust specific code and syntax as the rest of it is basically simple python.

Some standard python and locust imports

class TestUser(HttpUser):

We have to declare this class inheriting HttpUser, this particular class basically simulates one user doing certain tasks. Locust will spin multiple of these users only.

@task(1)def getUsers(self):
wait_time = constant(2)

here we have defined one function called getUsers which is basically a test case/task for load testing. it is basically a task for the users spun up by the
locust.

task

Notice the task tag at the beginning of the function, By tagging our function with this tag, we are telling locust that these are functions that need to be load tested.
We can define multiple functions like this. and tag these functions with the task tag.
Notice that I have used the task(1) attribute, we can totally omit the (1) part, but it is helpful when we have multiple tasks, as it defines the weight of the tasks.

So suppose there are two tasks A and B. Task A has weight as 3 while task B has weight as 1. Now during the locust load testing, the chance of a user picking up task A is 3 times more likely than task B, as we have defined the weights

if no weights are provided, then users will pick up all the tasks with the same probability.

wait_time

These attributes basically define the time in seconds, each user will wait after each task, if no wait time is defined, users will pick another task as soon as it finishes the previous one.
it can have four values

wait_time = constant(2)
wait_time = between(1,10)
wait_time = constant_throughput(2)
wait_time = constant_pacing(2)
  1. constant(x) — wait for a fix x seconds before starting a new task
  2. between(x,y)- wait anywhere between x to y seconds
  3. constant_throughput(x) — ensures that tasks run at most X time per second
  4. constant_pacing(x)— ensures task run at most once every X seconds

we can also define our own wait_time functions. Refer docs

with  self.client.get(url="/users?page="+i, name="/users?page=[pageNo]" , catch_response=True) as response:

this looks like a simple python GET request where we can define the URL, headers, payload, etc. Only two attributes here are locust specific

name Attribute

Locust gives performance statistics for each URL it requests. Here as we are using dynamic query parameters, hence we will technically request multiple different URLs, and the dashboard will show statistics for each of those URLs, although the only difference between them is a query parameter.
To tackle this situation we can use the name attributes, which will club these multiple statistics rows in a single row identified by the name attribute

catch_response Attribute

setting it as True will help us in validating a request as Success and Failures. If a Request is validated as failed, it will be counted as a failure and will be shown accordingly in the dashboard.
Now we can validate requests like this

if  response.status_code != 200 :
response.failure("request failed with wrong response code")

response.failure can be used to mark a request as failed, it will end the current task execution and on the locust dashboard’s Fail tab, you can see the failures along with the message you provided

there is also something as response.Success() also, it can be used when we want to explicitly mark a task as successful if it met certain conditions.
Note that if during the execution, we haven't encountered the response.failure , then our response is implicitly marked as successful

try :
data = response.json()
if data["data"] == None or len(data["data"]) == 0:
response.failure("Data list empty " )
dataList = data["data"]
for v in dataList:
if v["id"] <= 0:
response.failure("Invalid id " + id)
elif len(v["first_name"]) <= 0 or len(v["last_name"]) <= 0 or
len(v["avatar"]) <= 0:
response.failure("FirstName / lastName / avatar empty")
except JSONDecodeError as j:
print("Json decoded erorr" , j)
response.failure("Response could not be decoded as JSON")
except KeyError as k:
print("Key not found ", k)
response.failure("Response did not contain expected key")
except Exception as e:
print("Exception ",e)
response.failure("Something went worng bruh" + e)

some pretty simple API test cases, where we are checking for certain keys and values and accordingly calling response.failure

Locust Dashboard

Now you have written your locustfile, you have started your load-tested, stopped it at some point, now you have to analyze the result

Statistics

self-explanatory statistics like p90, RPS, etc. We can get other parameters like p50, p99 too if we download the locust report

charts

plotted charts for Total RPS, failures, response time, and number of users

Failures

if we validate a response as failed using response.failure it ends up here along with a message

Download Data

From here you can download different types of files that are self-explanatory.
The interesting one is the Download Report, it will download an HTML file which will contain all the charts and important statistics like RPS, p50, p90, etc.

P.S there is always more, For more advanced usage of the locust , I will advise you to kindly visit the locust official docs

See you in the next article, till then keep learning.

References

  1. Locust official docs
  2. reqres.in

--

--