TL;DR
- Locust = нагрузочное тестирование на Python (тесты — это просто Python код)
- Определяй поведение пользователей в
locustfile.pyс декораторами@task- Запуск с web UI (
locust) или headless (locust --headless)- Распределённый режим: один master + N workers для масштаба
- Метрики в реальном времени: RPS, время отклика, процент ошибок
Идеально для: Python-команд, нагрузочного тестирования API, разработчиков, предпочитающих код GUI Пропусти, если: Нужно GUI-построение тестов или широкая поддержка протоколов (используй JMeter) Время чтения: 12 минут
Твой API обрабатывает 100 запросов в секунду в продакшене. Приближается Чёрная пятница — выдержит ли он 10x? Лучше узнать заранее, чем от клиентов.
Locust позволяет писать нагрузочные тесты на Python. Никаких XML конфигов, сложных GUI. Просто Python код, симулирующий поведение пользователей.
Что такое Locust?
Locust — open-source фреймворк для нагрузочного тестирования на Python. Ты определяешь поведение пользователей как Python код, и Locust создаёт тысячи конкурентных пользователей для нагрузки на систему.
Почему Locust:
- Python-native — тесты это обычный Python код
- Масштабируемый — распределённый режим для миллионов пользователей
- Real-time UI — веб-дашборд показывает метрики в реальном времени
- Лёгкий — низкие ресурсы на пользователя
- Гибкий — тестируй любую систему с Python библиотеками
Установка
pip install locust
Проверка установки:
locust --version
Твой первый нагрузочный тест
Базовый Locustfile
# locustfile.py
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3) # Ожидание 1-3 секунды между задачами
@task
def homepage(self):
self.client.get("/")
@task(3) # В 3 раза чаще чем homepage
def api_endpoint(self):
self.client.get("/api/products")
Запуск теста
# Запуск с web UI
locust -f locustfile.py --host=https://api.example.com
# Открой http://localhost:8089
# Укажи количество пользователей и spawn rate
# Нажми Start
Headless режим (CI/CD)
locust -f locustfile.py \
--host=https://api.example.com \
--users 100 \
--spawn-rate 10 \
--run-time 5m \
--headless
Написание пользовательских сценариев
Множественные задачи
from locust import HttpUser, task, between
class ApiUser(HttpUser):
wait_time = between(0.5, 2)
@task(5)
def list_products(self):
self.client.get("/api/products")
@task(2)
def get_product(self):
self.client.get("/api/products/1")
@task(1)
def create_order(self):
self.client.post("/api/orders", json={
"product_id": 1,
"quantity": 2
})
Setup и Teardown
from locust import HttpUser, task, between
class AuthenticatedUser(HttpUser):
wait_time = between(1, 3)
def on_start(self):
# Выполняется один раз при старте пользователя
response = self.client.post("/api/login", json={
"username": "test",
"password": "password"
})
self.token = response.json()["token"]
def on_stop(self):
# Выполняется один раз при остановке пользователя
self.client.post("/api/logout")
@task
def protected_endpoint(self):
self.client.get("/api/profile", headers={
"Authorization": f"Bearer {self.token}"
})
Последовательные задачи
from locust import HttpUser, task, between, SequentialTaskSet
class UserFlow(SequentialTaskSet):
@task
def browse(self):
self.client.get("/products")
@task
def add_to_cart(self):
self.client.post("/cart", json={"product_id": 1})
@task
def checkout(self):
self.client.post("/checkout")
class EcommerceUser(HttpUser):
tasks = [UserFlow]
wait_time = between(1, 3)
Assertions и валидация
from locust import HttpUser, task
class ValidatingUser(HttpUser):
@task
def check_api(self):
with self.client.get("/api/status", catch_response=True) as response:
if response.status_code != 200:
response.failure(f"Got {response.status_code}")
elif response.elapsed.total_seconds() > 2:
response.failure("Too slow!")
elif "ok" not in response.text:
response.failure("Missing 'ok' in response")
else:
response.success()
Распределённое тестирование
Master Node
locust -f locustfile.py --master --host=https://api.example.com
Worker Nodes
# На каждой worker машине
locust -f locustfile.py --worker --master-host=192.168.1.100
Docker Compose
# docker-compose.yml
version: '3'
services:
master:
image: locustio/locust
ports:
- "8089:8089"
volumes:
- ./:/mnt/locust
command: -f /mnt/locust/locustfile.py --master -H https://api.example.com
worker:
image: locustio/locust
volumes:
- ./:/mnt/locust
command: -f /mnt/locust/locustfile.py --worker --master-host master
deploy:
replicas: 4
Понимание результатов
Ключевые метрики
| Метрика | Значение |
|---|---|
| RPS | Запросов в секунду (throughput) |
| Median | 50-й перцентиль времени отклика |
| 95%ile | 95% запросов быстрее этого значения |
| Failures | Процент неуспешных запросов |
| Users | Текущее количество симулированных пользователей |
Экспорт результатов
locust -f locustfile.py \
--headless \
--users 100 \
--spawn-rate 10 \
--run-time 5m \
--csv=results \
--html=report.html
CI/CD интеграция
GitHub Actions
# .github/workflows/load-test.yml
name: Load Tests
on:
schedule:
- cron: '0 2 * * *' # Ежедневно в 2:00
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Locust
run: pip install locust
- name: Run Load Test
run: |
locust -f locustfile.py \
--host=${{ secrets.API_URL }} \
--users 50 \
--spawn-rate 5 \
--run-time 2m \
--headless \
--csv=results
- name: Upload Results
uses: actions/upload-artifact@v4
with:
name: load-test-results
path: results*.csv
Locust с помощью ИИ
ИИ инструменты могут помочь писать и оптимизировать Locust тесты.
Что ИИ делает хорошо:
- Генерировать пользовательские сценарии из API спецификаций
- Создавать вариации данных для реалистичной нагрузки
- Предлагать пороговые значения производительности
- Конвертировать JMeter тесты в Locust
Что требует людей:
- Определение реалистичных паттернов поведения пользователей
- Установка подходящих уровней нагрузки
- Интерпретация результатов в бизнес-контексте
- Отладка специфичных production проблем
FAQ
Что такое Locust?
Locust — open-source Python-фреймворк для нагрузочного тестирования. Ты пишешь поведение пользователей на Python с декораторами @task, и Locust создаёт конкурентных пользователей для генерации нагрузки. Предоставляет web UI для мониторинга в реальном времени и поддерживает распределённое тестирование для масштаба.
Locust vs JMeter — что лучше?
Locust использует Python код (лучше для разработчиков, которым нужен контроль версий и поддержка IDE). JMeter использует GUI (проще для не-разработчиков). Locust легче и проще масштабируется с распределённым режимом. JMeter имеет более широкую поддержку протоколов и больше плагинов. Выбирай Locust для Python команд, JMeter для команд, которым нужен GUI или специфические протоколы.
Может ли Locust тестировать WebSockets?
Да, через кастомные клиенты. Архитектура Locust поддерживает любой протокол — ты реализуешь логику подключения на Python. Сообщество предоставляет библиотеки для WebSockets, gRPC и других протоколов. Locust управляет симуляцией пользователей и метриками, пока ты контролируешь реализацию протокола.
Сколько пользователей может симулировать Locust?
Одна машина обычно обрабатывает 1000-10000 конкурентных пользователей в зависимости от сложности сценария и доступных ресурсов. Для больших тестов используй распределённый режим с одним master, координирующим несколько workers. Это масштабируется до миллионов пользователей на кластере.
Официальные ресурсы
Смотрите также
- JMeter Tutorial - GUI-based нагрузочное тестирование
- k6 Load Testing - JavaScript нагрузочное тестирование
- API Performance Testing - Основы тестирования производительности
- Gatling Tutorial - Scala-based нагрузочное тестирование
