Locust позволяет описывать нагрузочные сценарии на Python. Виртуальный пользователь выполняет задачи, отправляет запросы и выдерживает заданные ожидания. Такой подход удобен команде, которая уже поддерживает Python-код и хочет выражать сложные пользовательские цепочки обычными функциями, сохраняя их понятными на review.
Прозрачный код не гарантирует корректную модель. Сценарий может хорошо работать технически и измерять вход в систему вместо заказа, использовать один объект для всех пользователей или остановиться на ресурсе генератора. Задача QA — проверить смысл нагрузки и связь статистики с реальным поведением сервиса.
Что моделирует пользователь
HttpUser предоставляет клиент для HTTP-запросов. У каждого пользователя есть собственный экземпляр и состояние сессии. Задачи выбираются по заданным весам, а wait_time определяет ожидание между выполнениями. Стандартная модель описывает пользователей, которые ждут завершения своих действий.
При замедлении ответов те же пользователи начинают меньше новых задач в секунду. Поэтому количество пользователей не равно RPS, а spawn-rate задаёт скорость их запуска, не частоту HTTP-запросов. Для независимого внешнего потока операций требуется отдельно проверить подходящую модель и достигнутую интенсивность.
Подготовка тестового контракта
Возьмём собственный каталог: GET /api/catalog должен вернуть статус 200 и объект с массивом items. Операция read-only, поэтому маленький пробный запуск не создаёт заказов и не требует сложной очистки. Это условие примера, а не свойство любого endpoint с методом GET.
Зафиксируйте размер каталога, состояние кэша и ограничения стенда. Определите, какие ответы считаются ошибочными и какие задержки допустимы. Установите конечный timeout, чтобы зависший запрос не оставлял пользователя занятым неопределённо долго и не делал профиль нагрузки случайным.
Минимальный locustfile
Сохраните код в locustfile.py в окружении с установленным Locust. catch_response позволяет отметить технически успешный HTTP-ответ как ошибку, если его содержимое нарушает контракт. В примере явно проверяются статус, JSON и тип коллекции.
from locust import HttpUser, task, between
class CatalogUser(HttpUser):
wait_time = between(1, 2)
@task
def catalog(self):
with self.client.get(
"/api/catalog", name="catalog", timeout=5,
catch_response=True
) as response:
if response.status_code != 200:
response.failure("Unexpected status")
return
try:
payload = response.json()
except ValueError:
response.failure("Invalid JSON")
return
if not isinstance(payload, dict) or not isinstance(
payload.get("items"), list
):
response.failure("items must be an array")locust -f locustfile.py --headless -u 5 -r 1 -t 1m --host https://qa.example.test --csv run01Домен заменяют адресом разрешённого стенда. Команда запускает до пяти пользователей, добавляя по одному в секунду, и сохраняет CSV с указанным префиксом. Это проверка механики; перед большим запуском убедитесь, что каждый запрос действительно выполняет нужную операцию.
Несколько задач и веса
Если добавить просмотр карточки и поиск с разными весами, Locust будет выбирать задачи с соответствующими вероятностями. Это не обещает точное соотношение в маленьком прогоне: случайный выбор и разная длительность действий влияют на фактические числа.
Для последовательной бизнес-цепочки объединяйте связанные действия в одну задачу либо используйте подходящую структуру сценария. Независимый случайный выбор «создать корзину» и «оплатить» без общего состояния не моделирует покупателя. Проверяйте фактическую долю операций по отчёту после запуска.
Сессия и корреляция
Авторизацию можно выполнить при старте пользователя, сохранив актуальный токен в его состоянии. HTTP-клиент сохраняет cookie между запросами. Не нужно входить перед каждым чтением, если реальные пользователи этого не делают: иначе проверяется другая доля нагрузки на сервис авторизации.
Идентификатор созданной корзины получают из ответа и используют в следующем шаге. При неуспешном входе или отсутствии ID цепочку нужно прекратить осмысленно. Множество вторичных 401 или 404 не должно маскировать первоначальную ошибку подготовки пользователя.
Данные и имена метрик
Для чтения используйте осмысленное распределение товаров и запросов. Один популярный товар проверяет горячий путь кэша; это полезный сценарий, если он так назван. Он не подтверждает работу поиска по большому разнообразному каталогу.
Динамические URL группируйте через name, чтобы каждый ID не создавал отдельную строку статистики. При этом сохраняйте возможность расследовать конкретную ошибку без записи секретов. Для изменяющих операций планируйте уникальные данные, проверку конечного состояния и безопасную очистку после эксперимента.
Ресурсы и распределённый запуск
Следите за CPU, памятью и сетью генератора. Произвольный Python-код, тяжёлый разбор ответа или несовместимая блокирующая библиотека могут мешать пользователям выполняться так, как ожидалось. Рост задержек требует отделить проблему генерации от проблемы сервера.
Распределённый запуск требует одинаковых сценариев и зависимостей на worker-узлах. Отдельно проверьте распределение данных, чтобы несколько процессов не использовали одни изменяемые записи ошибочно. Добавление workers помогает только после обнаружения ограничения генератора; оно не исправляет неверную модель или неправильный контракт.
Как принять результат
Смотрите фактическую интенсивность, ошибки содержимого, распределение задержек и динамику. Сопоставляйте их с пулом соединений, CPU, памятью, очередями и ожиданиями базы. Низкая средняя задержка при массовых быстрых отказах не означает успешный тест.
CLI-запуск и CSV сами по себе не реализуют все бизнес-пороги приёмки. Для автоматического решения настройте явные критерии через поддерживаемые события или последующий анализ результатов. Сохраните версию правил вместе со сценарием, чтобы разные прогоны оценивались одинаково.
Ошибки и полезный отчёт
Частые ошибки — считать spawn-rate запросами в секунду, оставить исключения проверки необработанными, сравнивать разные профили по одному среднему и перегружать генератор подготовкой данных. Нельзя делать вывод о длительной устойчивости по минутному учебному запуску.
Полезный отчёт показывает сценарий, условия, достигнутый поток, правильность результатов и причины нарушенных критериев. Для каталога ожидается корректный массив items во всех принятых ответах и выполнение согласованных порогов. Ограничения кэша, данных и стенда указывают рядом с выводом, чтобы команда могла правильно применить результат.