Chapter 15 · Using Locust as a Library
Chapter goals: Start load tests programmatically without the
locustCLI, 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:
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:
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:
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
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:
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:
# 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.statsprovides 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
- Write a Python script that starts a Locust test with 100 users, runs for 30 seconds, prints stats, and exits cleanly.
- Embed the script from exercise 1 into a pytest test with assertions on failure rate and response time.
- 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.