Chapter 16 · Plugins and Extensions
Chapter goals: Master the locust-plugins third-party library, custom LoadShape load profiles, stepped-pressure patterns, and how to extend Locust's Web UI.
16.1 locust-plugins: The Official Recommended Plugin Library
locust-plugins is a third-party extension library involving Locust core maintainers (current version 5.x), providing a range of out-of-the-box enhancements:
pip install locust-plugins| Module | Function |
|---|---|
locust_plugins.users | PlaywrightUser, SeleniumUser, KafkaUser, FtpUser, etc. |
locust_plugins.datasets | Data pools (CSV/JSON-driven) |
locust_plugins.monitors | Monitoring integration |
locust_plugins.listeners | Timescale/Grafana reporting |
Using PlaywrightUser for Browser-Level Load Testing
# locustfile.py
from locust_plugins.users import PlaywrightUser
class BrowserUser(PlaywrightUser):
tasks = [
{
"weight": 1,
"task": lambda page: page.goto("https://example.com"),
"name": "Visit homepage"
},
{
"weight": 2,
"task": lambda page: (
page.goto("https://example.com/login"),
page.fill("#username", "test"),
page.fill("#password", "pass"),
page.click("button[type=submit]")
),
"name": "Login flow"
}
]Why use PlaywrightUser
Traditional HttpUser only loads-tests the HTTP layer, missing JavaScript rendering time and frontend performance bottlenecks. PlaywrightUser launches a real browser to execute page operations — ideal for evaluating end-to-end user experience.
Using Data Pools for Parametrization
from locust_plugins.datasets import load_csv_data
class ApiUser(HttpUser):
# Load test data from CSV, loop-reuse
dataset = load_csv_data("test_users.csv")
@task
def login(self):
credentials = next(self.dataset)
self.client.post("/api/login", json={
"username": credentials["username"],
"password": credentials["password"]
})16.2 Custom Load Shape: LoadShape
By default, Locust sets a fixed concurrent user count via the Web UI or CLI. But real load-test scenarios often need dynamic load curves — stepped pressure, peak pulses, or day-night simulation.
Locust provides the LoadTestShape abstract base class; override tick() to control the user count at each moment:
from locust import HttpUser, task, between, LoadTestShape
class StagedShape(LoadTestShape):
"""Stepped pressure: 25 → 50 → 100 → 200 users"""
stages = [
{"duration": 60, "users": 25, "spawn_rate": 5},
{"duration": 120, "users": 50, "spawn_rate": 10},
{"duration": 180, "users": 100, "spawn_rate": 15},
{"duration": 240, "users": 200, "spawn_rate": 20},
]
def tick(self):
run_time = self.get_run_time()
for stage in self.stages:
if run_time < stage["duration"]:
return (stage["users"], stage["spawn_rate"])
return None # End the testAttach to your user class:
class MyUser(HttpUser):
host = "https://example.com"
load_shape = StagedShape # Attach the shape class
@task
def get_page(self):
self.client.get("/")16.3 Common Load Shapes
Ramp-up then hold
class RampHoldShape(LoadTestShape):
def tick(self):
run_time = self.get_run_time()
if run_time < 60:
# Ramp: 0 → 100 users in 60 seconds
return (int(run_time * 100 / 60), 100 / 60)
elif run_time < 300:
# Hold: 100 users for 4 minutes
return (100, 0)
return None # EndPeak pulse
class PulseShape(LoadTestShape):
def tick(self):
run_time = self.get_run_time()
cycle = run_time % 120 # 2-minute cycle
if cycle < 60:
return (100 * cycle / 60, 100 / 60) # Ramp up
else:
return (100 * (120 - cycle) / 60, -100 / 60) # Ramp down16.4 Chapter Summary
locust-pluginsextends Locust with PlaywrightUser, data pools, and monitoring;LoadTestShapelets you define arbitrary load curves via thetick()method;- Common shapes: stepped, ramp-hold, pulse — all expressed by returning
(users, spawn_rate)orNoneto end; - Attach a custom shape with
load_shape = MyShapeon the User class.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What does locust-plugins' PlaywrightUser enable?
2. What must the tick() method of LoadTestShape return?
3. How do you attach a custom LoadShape to a User class?
4. What is the difference between load_plugins datasets and manual CSV loading?
🛠️ Hands-On Exercises
- Install locust-plugins; write a PlaywrightUser that loads a page and asserts the title contains "Example".
- Implement a RampHoldShape (ramp to 100 users in 30s, hold for 2min, then end); run and verify the user count curve.
- Create a PulseShape that cycles 50→100→50 users every 60 seconds for 3 minutes; observe the RPS chart.
Proceed to Chapter 17: Performance Tuning and RPS Optimization.