Разработка нагрузочных тестов для сайта (Locust)

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка нагрузочных тестов для сайта (Locust)
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка нагрузочных тестов для сайта (Locust)

Locust — Python-инструмент нагрузочного тестирования. Сценарии пишутся как обычный Python-код, что даёт максимальную гибкость. Встроенный веб-интерфейс для управления тестами в реальном времени. Легко масштабируется горизонтально для высоких нагрузок.

Установка

pip install locust

Базовый сценарий

# locustfile.py
from locust import HttpUser, task, between, events
import json
import random

class WebsiteUser(HttpUser):
    wait_time = between(1, 3)  # ожидание между запросами 1-3 секунды

    def on_start(self):
        """Выполняется при старте каждого пользователя"""
        self.login()

    def login(self):
        response = self.client.post("/api/auth/login", json={
            "email": f"user{random.randint(1, 1000)}@test.com",
            "password": "testpassword",
        })
        if response.status_code == 200:
            self.token = response.json()["access_token"]
            self.client.headers.update({"Authorization": f"Bearer {self.token}"})
        else:
            self.token = None

    @task(3)  # вес 3 — выполняется в 3 раза чаще
    def browse_products(self):
        page = random.randint(1, 10)
        with self.client.get(f"/api/products?page={page}", catch_response=True) as response:
            if response.status_code == 200:
                data = response.json()
                if "data" not in data:
                    response.failure("Missing 'data' key in response")
            else:
                response.failure(f"Got {response.status_code}")

    @task(2)
    def view_product(self):
        product_id = random.randint(1, 500)
        self.client.get(f"/api/products/{product_id}")

    @task(1)
    def create_order(self):
        if not self.token:
            return
        self.client.post("/api/orders", json={
            "product_id": random.randint(1, 100),
            "quantity": random.randint(1, 3),
        })

Кастомные метрики

from locust import events
from locust.runners import MasterRunner

@events.request.add_listener
def on_request(request_type, name, response_time, response_length, response,
               context, exception, start_time, url, **kwargs):
    if exception:
        print(f"Request failed: {name} - {exception}")
    elif response_time > 2000:
        print(f"Slow request: {name} - {response_time}ms")


class FastApiUser(HttpUser):
    wait_time = between(0.5, 2)

    @task
    def search(self):
        start = time.time()
        with self.client.get("/api/search?q=laptop", catch_response=True) as response:
            duration = (time.time() - start) * 1000

            if response.status_code != 200:
                response.failure(f"Wrong status: {response.status_code}")
            elif duration > 1000:
                response.failure(f"Too slow: {duration:.0f}ms")

Несколько типов пользователей

class BrowsingUser(HttpUser):
    weight = 7  # 70% пользователей
    wait_time = between(2, 5)

    @task
    def browse(self):
        self.client.get("/api/products")

class PowerUser(HttpUser):
    weight = 3  # 30% пользователей
    wait_time = between(0.5, 1)

    @task
    def create_content(self):
        self.client.post("/api/products", json={
            "name": f"Product {random.randint(1, 9999)}",
            "price": random.uniform(100, 10000),
        })

Запуск

# С веб-интерфейсом
locust -f locustfile.py
# Открыть http://localhost:8089

# Headless режим
locust -f locustfile.py \
    --headless \
    --users 100 \
    --spawn-rate 10 \
    --run-time 5m \
    --host https://staging.example.com \
    --html report.html \
    --csv results

# Distributed mode (несколько машин)
# Master
locust -f locustfile.py --master --expect-workers=3

# Workers (на других серверах)
locust -f locustfile.py --worker --master-host=192.168.1.100

Пороговые значения (assertions)

# locustfile.py
from locust import events

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

    if total.fail_ratio > 0.01:
        print(f"FAIL: Error rate {total.fail_ratio:.2%} > 1%")
        environment.process_exit_code = 1

    if total.avg_response_time > 500:
        print(f"FAIL: Avg response time {total.avg_response_time:.0f}ms > 500ms")
        environment.process_exit_code = 1

    p99 = total.get_response_time_percentile(0.99)
    if p99 > 2000:
        print(f"FAIL: p99 {p99:.0f}ms > 2000ms")
        environment.process_exit_code = 1

Интеграция с CI/CD

# GitHub Actions
- name: Run Locust Load Test
  run: |
    locust -f locustfile.py \
      --headless \
      --users 50 \
      --spawn-rate 5 \
      --run-time 3m \
      --host ${{ vars.STAGING_URL }} \
      --html load-report.html
  continue-on-error: false

- name: Upload Report
  uses: actions/upload-artifact@v3
  with:
    name: load-test-report
    path: load-report.html

Срок реализации

Написание 3–5 сценариев Locust с типами пользователей и ассертами: 2–4 дня.