Running tests in a debugger

Running Locust in a debugger is extremely useful when developing your tests. Among other things, you can examine a particular response or check some User instance variable.

But debuggers sometimes have issues with complex gevent-applications like Locust, and there is a lot going on in the framework itself that you probably aren’t interested in. To simplify this, Locust provides a method called run_single_user:

from locust import HttpUser, run_single_user, task


class QuickstartUser(HttpUser):
    host = "http://localhost"

    @task
    def hello_world(self):
        with self.client.get("/hello", catch_response=True) as resp:
            pass  # maybe set a breakpoint here to analyze the resp object?


# if launched directly, e.g. "python3 debugging.py", not "locust -f debugging.py"
if __name__ == "__main__":
    run_single_user(QuickstartUser)

It implicitly registers an event handler for the request event to print some stats about every request made:

type    name                                           resp_ms exception
GET     /hello                                         38      ConnectionRefusedError(61, 'Connection refused')
GET     /hello                                         4       ConnectionRefusedError(61, 'Connection refused')

You can configure exactly what is printed by specifying parameters to run_single_user.

Make sure you have enabled gevent in your debugger settings. In VS Code’s launch.json it looks like this:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Run current file",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "gevent": true
        },
        {
            "name": "Run locust",
            "type": "python",
            "request": "launch",
            "module": "locust",
            "args": [
                "-f",
                "${file}",
                "--headless",
                "--users=5"
            ],
            "console": "integratedTerminal",
            "gevent": true
        }
    ]
}

If you want to the whole Locust runtime (with ramp up, command line parsing etc), you can do that too:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Locust: 5 users, with specific config file",
            "type": "python",
            "request": "launch",
            "module": "locust",
            "args": [
                "-f",
                "${file}",
                "--headless",
                "--users=5",
                "--config=${fileDirname}/../locust.conf"
            ],
            "console": "integratedTerminal",
            "gevent": true
        }
    ]
}

There is a similar setting in PyCharm.

Note

VS Code/pydev may give you warnings about:
sys.settrace() should not be used when the debugger is being used
It can safely be ignored (and if you know how to get rid of it, please let us know)

You can execute run_single_user multiple times, as shown in debugging_advanced.py.