Skip to content

Chapter 15 · Using Locust as a Library ​

Chapter goals: Start load tests programmatically without the locust CLI, master the Environment/Runner model, and learn to embed Locust in pytest and CI pipelines.

15.1 Environment and Runner Model ​

The Locust CLI tool is essentially a wrapper around these core classes:

text
Environment (test environment)
├── user_classes       → registered User class list
├── events             → event system
├── runner             → Runner instance (controls start/stop)
│   └── greenlet       → running coroutines
└── web_ui             → Web UI server (optional)

Minimal programmatic startup:

python
from locust.env import Environment
from my_locustfile import MyTestUser

# 1. Create Environment, register User classes
env = Environment(user_classes=[MyTestUser])

# 2. Create a local Runner
env.create_local_runner()

# 3. Start the test: 500 users, spawning 20 per second
env.runner.start(500, spawn_rate=20)

# 4. Block until the test completes
env.runner.greenlet.join()

15.2 Controlling Test Lifecycle ​

The Runner object provides full lifecycle control:

python
import time
from locust.env import Environment
from my_locustfile import MyTestUser

env = Environment(user_classes=[MyTestUser])
env.create_local_runner()

# Stepped pressure: gradually increase concurrent users
for users in [10, 50, 100, 200]:
    env.runner.start(users, spawn_rate=10)
    time.sleep(60)  # Hold each level for 60 seconds

# Stop manually
env.runner.quit()

Auto-stop with timeout ​

python
import gevent

def stop_after(seconds: int):
    gevent.sleep(seconds)
    print(f"{seconds}s elapsed — auto-stopping")
    env.runner.quit()

# Auto-end after 5 minutes
gevent.spawn(stop_after, 300)

env.runner.start(1000, spawn_rate=50)
env.runner.greenlet.join()
print("Test complete")

15.3 Programmatic Stats Access ​

Read live statistics directly from code without the Web UI:

python
from locust.env import Environment
from my_locustfile import MyTestUser

env = Environment(user_classes=[MyTestUser])
env.create_local_runner()
env.runner.start(100, spawn_rate=10)

# Wait 30 seconds
gevent.sleep(30)

# Read stats
stats = env.runner.stats
print(f"Total requests: {stats.total.num_requests}")
print(f"Failures: {stats.total.num_failures}")
print(f"RPS: {stats.total.current_rps:.2f}")
print(f"P95: {stats.total.avg_response_time:.0f}ms")

env.runner.quit()

15.4 Embedding in pytest ​

Locust tests can be embedded in pytest for mixed unit + load-test suites:

python
# tests/test_load.py
import pytest
from locust.env import Environment
from my_locustfile import MyTestUser


@pytest.fixture
def locust_run():
    env = Environment(user_classes=[MyTestUser])
    env.create_local_runner()
    env.runner.start(50, spawn_rate=5)
    yield env.runner
    env.runner.quit()


def test_load_stability(locust_run):
    import gevent
    gevent.sleep(30)  # Run for 30 seconds
    stats = locust_run.stats
    assert stats.total.num_failures == 0, f"Found {stats.total.num_failures} failures"
    assert stats.total.avg_response_time < 500, f"P50 too high: {stats.total.avg_response_time}ms"

Run with: pytest tests/test_load.py -v

15.5 Chapter Summary ​

  • Environment + Runner is the programmatic core; the CLI wraps these classes;
  • runner.start(users, spawn_rate) / runner.quit() for lifecycle control;
  • env.runner.stats provides real-time metrics without the Web UI;
  • Embed in pytest for mixed test suites with assertions on load-test results.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What is the minimal code to start a Locust test programmatically?

2. How do you read real-time statistics without the Web UI?

3. How do you embed Locust in a pytest test?

4. What does gevent.sleep() do in a programmatic Locust test?

🛠️ Hands-On Exercises ​

  1. Write a Python script that starts a Locust test with 100 users, runs for 30 seconds, prints stats, and exits cleanly.
  2. Embed the script from exercise 1 into a pytest test with assertions on failure rate and response time.
  3. Implement a stepped-pressure test: 10→50→100→200 users, holding each level for 30 seconds; print stats after each step.

Proceed to Chapter 16: Plugins and Extensions.