API testing is one of the most critical aspects of API development. You can build an API that works perfectly fine and returns the expected response. But have you tested what will happen when thousands of users simultaneously hit your API? Will it function as expected or return Error 500? Well, that depends on how far you have gone to load your API.

All of the above questions can be answered by a type of performance testing called load testing. Load testing is a technique that measures the performance of an API under various load conditions. It is a process that puts a lot of pressure on an API endpoint to check whether it returns the required output or not. Load testing thus helps identify the maximum capacity for your endpoints and reveals bottlenecks. It can help API developers obtain a qualitative idea of how well the API performs under real-world scenarios.

There are many tools available to help you load test APIs, such as Jmeter, Locust, LoadNinja, and Webload. In this article, we’re going to learn how to load test using Locust, an open-source load testing tool. But before that, let’s understand what Locust is.

Locust

Locust: a scalable user load testing tool written in Python. More info at Locust.io.

Locust is a load testing module for Python that is scalable and scriptable. It lets you create Python scripts that define the behavior of users, which makes it very developer-friendly. You can easily make conditional behaviors like looping or calculations. It runs every user in a separate co-routine which is called greenlet. This co-routine lets you write blocking codes of Python instead of callback functions.

Features of Locust:

  • Developer-friendly
  • Distributed and scalable
  • Comes with a web-based UI
  • You can use any protocol-based system

Now let’s try to test an API using Locust. To do so, let’s first create a very minimal API:

Prerequisites:

  • Python
  • Virtualenv
  • Flask
  • Locust

Step 1: Flask Installation and Server Setup

Let’s create a directory or folder for your project. We are using “locust-test” as the folder name, but you can pick any name for your project.

mkdir locust-test

Then,

cd locust-test

Now create a virtual environment for your project so that the dependencies don’t mess up the global package folder.

Execute the below command now:

virtualenv .

And then,

source bin/activate

Code Explanation:

What we are doing here is telling the module that the current folder can be used for the virtual environment, and then activating the virtual environment in the second step.

Now once you have activated the virtual environment, let’s install the flask package in that environment.

Now run the below command:

python3 -m pip install Flask

So far, we have created our project folder, installed and created a virtual environment for our project, and installed flask in the environment. Let’s head towards Step 2.

Step 2: Let’s Write Some Code

Now create a file app.py and paste the below code:

from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'This is my first API call!'

Code Explanation:

First, we are importing the flask module into our application and then defining the API route. The @ is used for defining the API route. We’re passing /, which means this is our base route.

Now run the API by using the below command:

flask run
Note: Keep the above command running.

Step 3: Creating a Locust Test

Now open another tab on your terminal in the same folder, i.e. locust-test, and paste the below command to install the Locust:

pip3 install Locust

Once Locust is installed, create a file locustfile.py. Make sure the file name is identical, and paste the below code:

from locust import HttpUser, task, between

class QuickstartUser(HttpUser):
    wait_time = between(5, 9)
    @task
    def getAPI(self):
        self.client.get("/")

Code Explanation:

This code is importing all the required modules from Locust like HttpUser, which is used to make HTTP calls, tasks to create users, and between to set an interval.

After that, we’re making a GET request.

Once it is done, save the file and run the below command:

locust --host=http://localhost:5000

We’re passing the URL of our API endpoint.

You’ll see something like this on the terminal:

Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)

This means that the Locust server is now running and is ready to test the API.

Step 4: Testing the API

Now go to URL http://0.0.0.0:8089 on your browser, and you should see the below screen:

Now in the first input box, fill in the number of users that you want to load on the API. In the second box, enter the interval between each call. For this example, I entered: 50 users and 2 seconds.

Once you hit Start Swarming, it’ll start the test, and you should be able to see the below screen:

To verify that your API is being consumed, you can check the first terminal where you ran the command flask run. On my terminal, it displayed something like this:

Now on the browser where Locust UI is running, click on the Chart tab. Here, you should be able to see how many requests are being made per second, the number of users, failures, and other data.

Now in the Activity Monitor (for Mac), you should see a lot of Python instances with multiple threads. This means that Python uses threads to create various users:

That’s it. You’re ready to load test your next set of APIs using Locust.

Final Words

Load testing can anticipate usage to help retain application stability. For example, consider a web application for a university with an API endpoint /results that returns exam results. Before the exam, students won’t use the web application because no one checks their marks prior to the exam. But, after the exam, sudden traffic jumps may cause the web application to crash when everyone checks their scores at once.

Do you see? Load testing a web application during development can help avoid crashes and make your application more robust.

In this article, we introduced how to use Locust, a powerful load testing tool. It creates multiple threads so that each thread can act as a single user. To take it one step further, you could also add conditions where you need an Auth header. Beyond API testing, Locust can be used to test normal Python code too.