Запуск без UI, CSV/HTML-отчёты, критерии прохождения, интеграция в GitHub Actions и GitLab CI.
Нагрузочный тест в CI/CD — это автоматический gatekeeping: если производительность деградировала, пайплайн падает до попадания изменений в production. Locust поддерживает headless-режим, экспорт отчётов и настраиваемые коды выхода для этого сценария.
Headless-режим запускает Locust без Web UI — нужен для автоматизации в CI/CD, где никто не нажимает кнопки в браузере. Флаг --headless требует явного указания числа пользователей и spawn rate:
locust -f locustfile.py \
--headless \
--host http://staging.example.com \
--users 100 \
--spawn-rate 10 \
--run-time 2mПосле завершения (--run-time истёк или LoadTestShape вернул None) Locust выведет итоговую статистику в stdout и завершит процесс.
Код выхода процесса Locust важен для CI/CD:
0 — тест завершился без ошибок (статистика могла содержать failures, но процесс завершился штатно)1 — были failures (если установлен флаг --exit-code-on-error 1)2 — критическая ошибка (не смог запустить тест, не нашёл locustfile и т.д.)Флаг --exit-code-on-error задаёт код выхода при наличии хотя бы одной ошибки запроса:
locust -f locustfile.py --headless \
--users 100 --spawn-rate 10 --run-time 1m \
--exit-code-on-error 1Если в тесте были failures — процесс завершится с кодом 1, CI/CD-системы (GitHub Actions, GitLab CI) воспримут это как сбой шага.
Для сохранения результатов и последующего анализа используйте --csv:
locust -f locustfile.py --headless \
--users 100 --spawn-rate 10 --run-time 2m \
--csv=results/locust_reportLocust создаст три файла:
locust_report_stats.csv — агрегированная статистика по каждому эндпоинтуlocust_report_stats_history.csv — метрики по времени (каждые 10 секунд)locust_report_failures.csv — список упавших запросов с ошибкамиФайл _stats.csv содержит: Name, Request Count, Failure Count, Median Response Time, 95%ile, 99%ile, Average Content Size, Min Response Time, Max Response Time, Average Response Time, RPS, Failures/s.
Locust умеет генерировать HTML-отчёт с графиками — удобно для просмотра результатов без CI-инструментов:
locust -f locustfile.py --headless \
--users 100 --spawn-rate 10 --run-time 2m \
--html=results/report.htmlHTML-отчёт включает интерактивные графики (RPS, латентность, число пользователей по времени) и таблицу со статистикой. Этот файл можно опубликовать как артефакт в GitHub Actions или GitLab CI.
Пример workflow для запуска нагрузочного теста на каждый PR:
name: Load Test
on:
pull_request:
branches: [main]
jobs:
load-test:
runs-on: ubuntu-latest
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: Start test server
run: |
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 &
sleep 3 # Ждём, пока сервер поднимется
- name: Run load test
run: |
locust -f tests/locustfile.py \
--headless \
--host http://localhost:8000 \
--users 50 \
--spawn-rate 5 \
--run-time 60s \
--csv=results/locust \
--html=results/report.html \
--exit-code-on-error 1
- name: Upload HTML report
uses: actions/upload-artifact@v4
if: always()
with:
name: locust-report
path: results/
- name: Check p95 latency
run: python scripts/check_sla.py results/locust_stats.csvШаг Check p95 latency вызывает скрипт, который парсит CSV и завершается с ненулевым кодом, если SLA нарушены:
# scripts/check_sla.py
import csv
import sys
P95_LIMIT_MS = 500
with open(sys.argv[1]) as f:
reader = csv.DictReader(f)
violations = []
for row in reader:
if row["Name"] == "Aggregated":
continue
p95 = float(row.get("95%", 0))
if p95 > P95_LIMIT_MS:
violations.append(f"{row['Name']}: p95={p95}ms > {P95_LIMIT_MS}ms")
if violations:
print("SLA нарушены:")
for v in violations:
print(f" - {v}")
sys.exit(1)
print("Все SLA соблюдены")load_test:
stage: test
image: python:3.12-slim
script:
- pip install locust
- locust -f tests/locustfile.py
--headless
--host $STAGING_URL
--users 100
--spawn-rate 10
--run-time 2m
--csv=locust_results
--exit-code-on-error 1
artifacts:
when: always
paths:
- locust_results_stats.csv
- locust_results_failures.csv
reports:
junit: locust_results_stats.csvВ CI/CD удобно параметризовать нагрузочный тест через переменные окружения — числа пользователей могут отличаться для разных окружений:
locust -f locustfile.py \
--headless \
--host "${TARGET_URL:-http://localhost:8000}" \
--users "${LOCUST_USERS:-50}" \
--spawn-rate "${LOCUST_SPAWN_RATE:-5}" \
--run-time "${LOCUST_RUN_TIME:-60s}"Или через файл locust.conf в корне проекта (Locust читает его автоматически):
headless = true
users = 100
spawn-rate = 10
run-time = 2m
host = http://staging.example.com
csv = results/locust
exit-code-on-error = 1С файлом конфигурации команда запуска сводится к locust -f tests/locustfile.py.
Нагрузочный тест в CI должен быть быстрым и предсказуемым. Рекомендации:
--run-time разумным значением (60–120 секунд), чтобы не замедлять пайплайн_stats_history.csv как артефакт — он позволяет строить тренды производительности между PRВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.