Skip to main content

Drupal 8 Load Testing with Locust

15 min read
Jan 28, 2020
Sep 21, 2023
A side-by-side image of the Drupal 8 and Locust logos.

Load testing is an essential practice for Drupal 8 development and Locust is recommended web-based, open-source load testing solution.

Load-testing is an essential best practice for Drupal 8 development. Quantifying how much traffic a site can sustain is critical information both during development and prior to launch. 

The reasons for doing so are significant and wide-ranging:

  • Determine hosting needs
  • Identify under-performing code
  • Test the efficiency of candidate contributed modules
  • Quantify how performance is impacted as content grows
  • Document pre-launch performance to facilitate future troubleshooting

 

Locust as a Load-testing Solution

Locust is a web-based, open-source tool. It was created to be easy-to-use via its user interface, while also being customizable via Python test scripts. For example, it allows for the ability to simulate multiple users concurrently submitting a Drupal webform multiple times. It can also run distributed tests with instances running on multiple machines.

 

Installing Locust

python3 -m pip install locustio

Install the "Beautiful Soup" python library to facilitate user login

python3 -m pip install bs4

 

Example Test Script

from locust import HttpLocust, TaskSet, between
from bs4 import BeautifulSoup
def index(self):
    self.client.get("/")
def about(self):
    self.client.get("/about")
def drupalLogin(self):
    # Get form build ID to pass back to Drupal on login.
    response = self.client.get("/user")
    content = BeautifulSoup(response.content)
    build_id = content.body.find('input', {'name': 'form_build_id'})['value']
    self.client.post("/user/login", {
        "name": "testusername",
        "pass": "testpassword",
        "form_id": "user_login_form",
        "form_build_id": build_id,
        "op": "Log in"
    })
def drupalLogout(self):
    self.client.get("/user/logout")
class UserBehavior(TaskSet):
    tasks = {index: 1, about: 1}
    def on_start(self):
        drupalLogin(self);
    def on_stop(self):
        drupalLogout(self)
class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    wait_time = between(5.0, 9.0)

In this example, 5 users log in to Drupal and then each user accesses either the front page or the / about page every 5-9 seconds. The "Hatch rate" of 1 adds an additional use each second until a total of 5 concurrent users are actively running the script. This helps to simulate a more natural increase in traffic.  Finally, all users log out of Drupal when testing ends.

 

Running a Test

locust -f ./locust_test.py

Here is the UI form for initializing the test:

The UI form for initializing the test

Here is a screenshot of the data table this test produced:

Screen shot of the data the test produced

Here are PNG graph images generated by Locust during this test:

Graph showing the number of requests per second.

Graph showing response times.

PNG graph images generated by Locust during the test

Tests can also be run without the UI. This is useful for automation or for running tests in a remote environment:

locust -f ./locust_test.py --no-web -c 5 -r 1 -H https://target.domain

This approach has successfully been tested in a CentOS 7 environment.

 

Load-Testing in the Development Cycle

Since tests are fairly straightforward to write and run, it is feasible to perform load-testing throughout the development process.

Early in the development phase, tests could be more simple and generic. For example, visiting the front page, logging in, and logging out. These initial tests could be site-agnostic for reuse across multiple projects. Then, more site-specific tests can be added as the project takes shape,.

An approach for this might include load-testing directions within pull requests or, potentially, automation could kick off tests following a PR merge so a snapshot of performance is captured with each code change.

 

Next Steps

Locust is a simple yet flexible open-source tool for quantifying performance throughout the development cycle. Interested in load-testing or test-driven development for your Drupal 8 site?  Contact us today.

Resources

 

Josh looking at the camera with arms crossed
By Josh Estep

Josh has been a Drupal Developer for more than 10 years and has a B.S. in Computer Science from Furman University. While in college, he played French Horn in the orchestra and studied abroad at James Cook University in Cairns, Australia.

How may I assist you?