In our last post we learned about using ApacheBench (ab) to do some simple load testing.

The drawbacks of ab is it's simplicity. It only tests your server. It never hits any web pages.

Enter Locust.

Locust is an easy-to-use, distributed, user load testing tool. Intended for load testing web sites (or other systems) and figuring out how many concurrent users a system can handle.

Some of the things I like about Locust:

  • Plain old Python (2.6+ but not 3.x)
  • You can start small but if you want to distribute your testing Locust will scale
  • Simple web interface

Since Locust is Python based installation is a matter of:

pip install locustio

Next create a locustfile.py:

from locust import HttpLocust, TaskSet, task

class WebsiteTests(TaskSet):
    @task(1)
    def index(self):
        self.client.get("/")

class WebsiteUser(HttpLocust):
    host = "http://thecrumb.com"
    task_set = WebsiteTests
    min_wait=5000
    max_wait=9000

This is a barebones Locust test. It imports Locust, defines a class that inherits Locust (WebsiteUser) and another class to define a test (WebsiteTests).

We also define a host and some wait variables.

Now if you run Locust - you will get a message similar to:

jim:~/locust$ locust
[2016-06-12 18:01:00,249] jim-pc/INFO/locust.main: Starting web monitor at *:8089
[2016-06-12 18:01:00,250] jim-pc/INFO/locust.main: Starting Locust 0.7.5

Now crank up your browser and visit http://localhost:8089

You should see something like:

Locust screenshot

Now you can enter in the number of users and the 'hatch' rate and start swarming!

WARNING: Be careful! You are load testing an environment. It is easy to overwhelm a server if not setup correctly. You don't want to run this against your production site!

You should see something happening:

Locust screenshot

In our test we only defined one path "/" so the test isn't going to do very much. Lets make some changes and run it again:

from locust import HttpLocust, TaskSet, task

class WebsiteTests(TaskSet):
    def on_start(self):
        """ on_start is called when a Locust start before any task is scheduled """

    @task(10)
    def index(self):
        self.client.get("/")

    @task(5)
    def about(self):
        self.client.get("/pages/about.html")

    @task(1)
    def resume(self):
        self.client.get("/pages/resume.html")

class WebsiteUser(HttpLocust):
    host = "http://www.thecrumb.com"
    task_set = WebsiteTests
    min_wait=5000
    max_wait=9000

We've added a few more tasks with different paths to test. Each task is also weighted. My index task will run 10x more often than my resume task. If you have areas of your site you are more concerned with you can give them more weight in your tests.

This will also be reflected when you run your test:

You should see something happening:

Locust screenshot

One thing to note - the Locust file has no time threshold. You must manually stop the tests.

Run

locust --help

For available options and checkout the Locust docs for more details on these options and how to run Locust distributed. You can submit post requests with Locust (ie login), and you can scrape pages with something like BeautifulSoup for URLs to visit instead of hardcoding them into your tests.

Remember - it's Python so the sky (and your imagination) is the limit on what you can do.

Next post we will checkout Blazemeter a site where you can run all your tests: JMeter, Locust and more.

Published on Monday, June 13 2016     Tags: testing tools

COMMENT / SHARE