Подробнее на официальном сайте: https://docs.locust.io/en/latest/quickstart.html
Создание простого теста:
from locust import HttpUser, task, between class Exists(HttpUser): wait_time = between(1, 5) @task(1) def auth(self): self.client.get("/exists")
Для проверки можно выполнить:
import requests as r base_url = 'http://localhost:5007/release' r.get(base_url + '/exists') # <Response [200]>
Авторизация
from locust import HttpUser, task, between class AuthorizationUser(HttpUser): wait_time = between(1, 5) @task(1) def auth(i): i.client.post('/auth', { "UserName": "user", "Password": "1234", "Version": "0.0.0.0" })
Для проверки в консоли можно выполнить:
import requests as r base_url = 'http://localhost:5007/release' r.post(base_url + '/auth', { "UserName": "user", "Password": "1234", "Version": "0.0.0.0" }) #<Response [200]> >>> response = r.post(base_url + '/auth', { "UserName": "user", "Password": "1234", "Version": "0.0.0.0" }) response.json() # {'token': 'dXNlcjoxMjM0', 'user': {'id': 2, 'login': 'user', 'claims': '.user.', 'date': '2022-06-21T04:14:27.559Z'}, 'ip': '::1'}
Переопределение статуса ответа:
def exists(i): with i.client.get('/exists', catch_response=True) as response: if response.status_code == 200: response.success() else: response.failure(f'status code is {response.status_code}')
Параметр catch_response=True обязателен, иначе вывод ошибки в response.failure не будет.
Группировка запросов для оптимального просмотра:
with self.client.get(f'/photos/{photo_id}', catch_response=True, name='/photos/[id]') as response: if response.status_code == 200: response.success() else: response.failure(f'status code is {response.status_code}')
Параметр name=’/photos/[id]’ предназначен для группировки результатов по «маске«.
Создание собственного исключения:
class FlowException(Exception): pass ... def check_flow(self): new_post = {...} response = self.client.post('/posts', json=new_post) if response.status_code != 201: raise FlowException('post not created') post_id = response.json().get('id')
- raise FlowException(‘post not created’) — остановка сценария. Можно в сценарии указать и return, но при этом во вкладке Exception мы не увидим ошибки
- response.json().get(‘id’) — чтение id из результата
Сценарий временного хранения:
from locust import HttpLocust, TaskSet, task import random as r # class UserBehavior(TaskSet): # def __init__(self, parent): # super(UserBehavior, self).__init__(parent) # self.created_posts = list() class UserBehavior(TaskSet): created_posts = [] @task(1) def create_post(self): ... post_id = response.json().get('id') self.created_posts.append(host_id) @task(10) def read_post(self): if len(self.created_posts) == 0: return post_id = r.chioce(self.created_posts)
- r.chioce(self.created_posts) — рандомный выбор записи
- в закомментированной части указан пример реализации, чтобы набор постов для каждого пользователя был своим
Выполнение под сценариев:
class Todo(TaskSet): @task(3) def index(self) self.client.get('/todos') @task(1) def stop(self): self.interrupt() class UserBehavior(TaskSet): tasks = {Todo: 1} @task(3) def index(self): self.client.get('/') @task(2) def posts(self): self.client.get('/posts')
- tasks = {Todo: 1} — объявление под задачи
- self.interrupt() — чтобы принудительно завершить тест
Передача заголовка авторизации:
... import requests class UserBehavior(TaskSet): def on_start(self): response = requests.post('/login', {...}) self.client.headers.update({'Authorization': response.headers.get('RPC-Authorization')}) # get token from cookies self.client.headers.update({'Authorization': response.cookies.get('RPC-Authorization')}) # get token from body self.client.headers.update({'Authorization': str(response.content.decode().find('google'))}) @task(21) def posts(self): ...
Распределенное тестирование.
- Мастер — экземпляр, который собирает данные со slave «машин»
- Slave — экземпляры, которые производят тестирование, и передают данные мастеру
locust -f test.py --master --host=http://localhost:3000
locust -f test.py --slave --master-host=http://localhost
Запуск теста без web-интерфейса:
locust -f test.py --host=http://localhost --no-web -c 10 -r 2 --run-time 1m --csv=test_res
- no-web — не создаем веб-интерфейс
- c — количество пользователей
- r — прирастание пользователей в секунду
- run-time — время теста в минутах (параметр времени)
- csv — результат теста
Игнорирование сертификата HTTPS:
self.client.post('/posts', data, verify=False)
verify=False — не будет проверки сертификата
Логирование:
locust -f main.py --host=http://localhost --logfile=locustfile.log
Подробнее тут https://docs.locust.io/en/stable/logging.html
Статья с Хабр
Дополнительное видео: