A template-driven Locust performance testing application with dynamic configuration and MCP server readiness.
- Python 3.11+ (tested with Python 3.13)
- Virtual environment support
- Clone and setup the project:
git clone <repository-url>
cd spec-test- Create and activate virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate- Install dependencies:
pip install locust>=2.23,<3.0Run with example configuration:
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless --run-time 30sWith CLI overrides:
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--users 5 --spawn-rate 1 --run-time 10s --host https://httpbin.orgWith environment variables:
CONFIG_PATH=data/config.example.json HOST=https://httpbin.org USERS=3 \
locust -f locustfile.py --headless --run-time 15sConfiguration templates are stored in the data/ directory as JSON files:
data/config.example.json- Basic example configurationdata/config.openapi.json- Advanced OpenAPI-style configuration with multiple HTTP methods
Required fields:
host(string) - Target host URLusers(integer) - Number of concurrent usersspawn_rate(float) - Users spawned per secondrun_time(string) - Test duration in Locust format (e.g., "5m", "30s")
Optional fields:
endpoints(array) - List of endpoint configurationsthink_time_seconds(float) - Wait time between requestsseed(integer) - Random seed for deterministic resultsreport_html(string) - HTML report output path
Each endpoint in the endpoints array supports:
{
"path": "/api/users",
"method": "GET",
"weight": 2,
"headers": {
"Authorization": "Bearer token",
"Content-Type": "application/json"
},
"payload": {
"name": "Test User",
"email": "test@example.com"
}
}path(required) - API endpoint pathmethod(optional) - HTTP method (GET, POST, PUT, DELETE), defaults to GETweight(optional) - Relative weight for selection probability, defaults to 1headers(optional) - Custom HTTP headerspayload(optional) - JSON request body for POST/PUT requests
Values are resolved in this order (highest to lowest priority):
- CLI arguments -
--users,--spawn-rate,--run-time,--host - Environment variables -
USERS,SPAWN_RATE,RUN_TIME,HOST,REPORT_HTML - Template file - JSON configuration file
| Variable | Description | Example |
|---|---|---|
CONFIG_PATH |
Path to configuration template | data/config.json |
USERS |
Number of concurrent users | 10 |
SPAWN_RATE |
Users spawned per second | 2.0 |
RUN_TIME |
Test duration | 5m |
HOST |
Target host URL | https://api.example.com |
REPORT_HTML |
HTML report output path | reports/test.html |
{
"host": "https://httpbin.org",
"users": 5,
"spawn_rate": 1,
"run_time": "1m",
"endpoints": [
{"path": "/get", "method": "GET", "weight": 1},
{"path": "/status/200", "method": "GET", "weight": 2}
]
}{
"host": "https://api.example.com",
"users": 10,
"spawn_rate": 2,
"run_time": "5m",
"think_time_seconds": 1.0,
"endpoints": [
{
"path": "/api/v1/users",
"method": "GET",
"weight": 5,
"headers": {"Authorization": "Bearer token"}
},
{
"path": "/api/v1/users",
"method": "POST",
"weight": 2,
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer token"
},
"payload": {
"name": "Test User",
"email": "test@example.com"
}
},
{
"path": "/api/v1/users/123",
"method": "PUT",
"weight": 1,
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer token"
},
"payload": {
"name": "Updated User"
}
},
{
"path": "/api/v1/users/123",
"method": "DELETE",
"weight": 1,
"headers": {"Authorization": "Bearer token"}
}
]
}# Quick health check with 1 user for 10 seconds
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--users 1 --spawn-rate 1 --run-time 10s# Load test with 50 users, ramping up 5 per second for 5 minutes
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--users 50 --spawn-rate 5 --run-time 5m# Stress test with high user count
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--users 100 --spawn-rate 10 --run-time 10m --html data/results/stress-test.html# Test against local development server
CONFIG_PATH=data/config.example.json HOST=http://localhost:8000 \
locust -f locustfile.py --headless --users 5 --run-time 30sspec-test/
βββ locustfile.py # Main Locust implementation
βββ data/
β βββ config.example.json # Example configuration
β βββ config.openapi.json # Advanced OpenAPI example
β βββ results/
β βββ README.md # Generated reports directory
βββ docs/
β βββ mcp-mapping.md # MCP server conversion guide
βββ specs/
βββ 001-i-m-building/ # Project specifications
The application validates configuration on startup and provides clear error messages:
# Test with invalid configuration
CONFIG_PATH=data/config.bad.json locust -f locustfile.py --headless
# Output: Configuration error: Missing required configuration keys: hostOn startup, the application prints the resolved configuration showing the source of each value:
=== Resolved Configuration ===
host: https://httpbin.org (from env:HOST)
users: 5 (from env:USERS)
spawn_rate: 2 (from template:data/config.example.json)
run_time: 30s (from cli)
...
Generate detailed HTML reports with performance metrics:
# Generate HTML report
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--run-time 2m --html data/results/performance-report.htmlReports include:
- Request statistics (response times, throughput, error rates)
- Response time percentiles
- Error details
- Charts and graphs (in web UI mode)
For interactive testing and real-time monitoring:
# Start web UI (remove --headless)
CONFIG_PATH=data/config.example.json locust -f locustfile.py
# Access at http://localhost:8089Use seeds for reproducible test results:
{
"seed": 42,
"endpoints": [...]
}Add realistic delays between requests:
{
"think_time_seconds": 2.5,
"endpoints": [...]
}Control traffic distribution with weights:
{
"endpoints": [
{"path": "/api/read", "weight": 8}, # 80% of requests
{"path": "/api/write", "weight": 2} # 20% of requests
]
}This implementation is designed to be easily converted to a Model Context Protocol (MCP) server. See docs/mcp-mapping.md for detailed conversion guidance.
1. "You must specify the base host" error:
- Ensure
hostis specified in configuration or via--hostflag
2. "Missing required configuration keys" error:
- Check that all required fields are present in your configuration file
3. JSON parsing errors:
- Validate your JSON configuration file syntax
4. Import errors:
- Ensure Locust is installed:
pip install locust>=2.23,<3.0 - Activate your virtual environment
Add verbose output for debugging:
# Run with verbose logging
CONFIG_PATH=data/config.example.json locust -f locustfile.py --headless \
--run-time 30s -L DEBUGThis project follows the .specify methodology with constitutional development principles. See .specify/memory/constitution.md for implementation requirements.
This project is part of a specification-driven development experiment following constitutional programming principles.
Version: 1.0.0 | Last Updated: September 22, 2025