Skip to content

Chapter 18 · CI/CD Integration ​

Chapter goals: Embed Locust load tests into GitHub Actions pipelines, implement headless automatic execution, performance threshold judgments, result archiving, and scheduled load testing.

18.1 Headless Mode Execution ​

CI environments have no GUI. Locust provides --headless to skip the Web UI and run directly:

bash
# Basic usage: 10 users, 2 spawned per second, 60 seconds duration
locust -f locustfile.py --headless \
  --users 10 \
  --spawn-rate 2 \
  --run-time 60s \
  --host https://staging.example.com

Key parameters:

ParameterShortDescription
--headless—Do not start the Web UI
--users / -u-uTarget concurrent users
--spawn-rate / -r-rUser spawn rate (users/second)
--run-time / -t-tTest duration (e.g., 60s, 5m)
--host-HBase URL of the system under test

Exit code mechanism

Locust exits with a non-zero code when there are request failures. Combined with the events.quitting listener from Chapter 16 that sets process_exit_code = 1, CI can correctly mark the build as failed when failure rate or p95 exceeds thresholds.

18.2 GitHub Actions Workflow ​

Complete GitHub Actions configuration example:

yaml
# .github/workflows/load-test.yml
name: Performance Test

on:
  workflow_dispatch:        # Manual trigger
    inputs:
      target_url:
        description: 'Target URL'
        required: true
        default: 'https://staging.example.com'
      user_count:
        description: 'Concurrent users'
        required: false
        default: '50'
  schedule:
    - cron: '0 6 * * 1'     # Every Monday 6:00 UTC

jobs:
  load-test:
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: pip install locust

      - name: Run load test
        id: locust
        run: |
          locust -f locustfile.py --headless \
            --users ${{ github.event.inputs.user_count || '50' }} \
            --spawn-rate 10 \
            --run-time 120s \
            --host ${{ github.event.inputs.target_url }} \
            --csv results/perf_report \
            --html results/report.html \
            --only-summary

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: locust-results-${{ github.run_id }}
          path: results/

18.3 Adding Performance Threshold Gates ​

Define pass/fail criteria using the events.quitting hook:

python
# locustfile.py
from locust import events

@events.quitting.add_listener
def check_thresholds(environment, **kwargs):
    stats = environment.runner.stats

    # Fail if failure rate > 1%
    if stats.total.num_failures / max(stats.total.num_requests, 1) > 0.01:
        environment.process_exit_code = 1
        print("FAIL: failure rate exceeds 1%")

    # Fail if p95 > 500ms
    p95 = stats.total.avg_response_time  # Note: use proper percentile calc
    if p95 > 500:
        environment.process_exit_code = 1
        print(f"FAIL: p95 response time {p95}ms exceeds 500ms")

When process_exit_code = 1, the CI step fails and the pipeline blocks merge.

18.4 Chapter Summary ​

  • --headless + CLI flags replace the Web UI for CI;
  • GitHub Actions: checkout → setup Python → install locust → run headless → upload artifacts;
  • events.quitting hook sets process_exit_code = 1 on threshold breach to block CI;
  • Schedule with cron for nightly regression load tests.

🧪 随堂测验

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

1. What flag makes Locust suitable for CI pipelines?

2. How do you make a CI pipeline fail when p95 exceeds a threshold?

3. What is the purpose of --only-summary in headless mode?

4. How do you schedule a nightly load test in GitHub Actions?

🛠️ Hands-On Exercises ​

  1. Write a GitHub Actions workflow that runs a headless Locust test on every push to main; upload CSV and HTML artifacts.
  2. Add a events.quitting listener that fails the build if p95 > 500ms or failure rate > 1%.
  3. Add a schedule: cron: '0 6 * * 1' trigger for weekly regression; verify it runs automatically.

Proceed to Chapter 19: Monitoring and Results Analysis.