Нагрузочное тестирование: цели, виды и как построить сценарий

Нагрузочное тестирование: цели, виды и как построить сценарий Полезное

Нагрузочное тестирование (load testing) — это проверка того, как система ведет себя под ожидаемой одновременной нагрузкой: сколько запросов в секунду держит, за какое время отвечает и когда начинает деградировать. В отличие от функциональных тестов, которые проверяют «работает ли фича правильно», нагрузочное отвечает на вопрос «работает ли она достаточно быстро и стабильно, когда пользователей много».

Ниже разберем, зачем нужно нагрузочное тестирование, какие у него виды (и чем они отличаются друг от друга), какие метрики измерять, какими инструментами пользоваться и как собрать первый сценарий на k6.

Зачем нужно нагрузочное тестирование

Три главные цели, ради которых запускают нагрузочные тесты:

  • Проверить поведение под нагрузкой. Убедиться, что при целевом числе пользователей система отвечает в рамках согласованных требований (например, p95 времени ответа меньше 500 мс, доля ошибок меньше 1%).
  • Найти узкие места. Понять, что упирается первым: база данных, пул соединений, CPU приложения, сеть или сторонний сервис. Узкое место — это компонент, который ограничивает пропускную способность всей цепочки.
  • Определить предел. Найти точку, после которой система перестает справляться: растет время ответа, появляются ошибки, падает пропускная способность.

Дополнительно нагрузочные тесты помогают планировать инфраструктуру (сколько серверов заложить под рост аудитории) и ловить утечки ресурсов, которые проявляются только за часы работы.

Важно не путать: нагрузочный тест не заменяет функциональные проверки. Сначала система должна быть корректной, и только потом имеет смысл мерить ее производительность.

Ключевые метрики: что именно измерять

Нагрузочный тест ценен не фактом запуска, а метриками. Минимальный набор, который смотрят почти всегда:

  • Throughput (пропускная способность) — сколько запросов система обрабатывает в единицу времени. Часто выражается в RPS (requests per second, запросов в секунду). Это мера «сколько работы».
  • Latency (время ответа) — сколько времени уходит на один запрос. Это мера «как быстро».
  • Error rate (доля ошибок) — процент запросов, завершившихся ошибкой (таймаут, код 5xx, разрыв соединения). Под нагрузкой ошибки часто важнее скорости.

Отдельно стоит различать среднее время ответа и перцентили. Среднее обманчиво: несколько очень быстрых ответов маскируют медленные. Поэтому смотрят перцентили.

Перцентиль p95 — это значение, ниже которого лежит 95% замеров; p99 — 99%. Если p95 времени ответа равен 500 мс, значит 95% запросов уложились в 500 мс, а 5% были медленнее. Именно эти «медленные хвосты» портят опыт реальным пользователям, поэтому требования формулируют через p95/p99, а не через среднее.

Виды нагрузочного тестирования

Разные вопросы требуют разного профиля нагрузки. Ниже — основные виды и чем они отличаются. Ключевое различие между load, stress и soak: load держит ожидаемую нагрузку, stress намеренно превышает предел, soak растягивает умеренную нагрузку во времени.

Вид Профиль нагрузки На какой вопрос отвечает
Load (нагрузочный) Ожидаемая целевая нагрузка, удерживается ровно Держим ли мы штатный трафик в рамках требований?
Stress (стресс) Нагрузка растет выше ожидаемой, до отказа Где предел и как система деградирует за ним?
Spike (пиковый) Резкий скачок нагрузки за секунды Переживем ли мы внезапный всплеск (распродажа, рассылка)?
Soak / endurance (на выносливость) Умеренная нагрузка много часов Есть ли утечки памяти, деградация со временем?
Volume (объемный) Большой объем данных в базе или запросе Как система работает на больших данных?

Различие load и stress — в намерении. Load-тест проверяет соответствие требованиям при штатной нагрузке и в идеале проходит «зелено». Stress-тест сознательно ломает систему, чтобы увидеть точку отказа и характер деградации (плавно замедляется или падает целиком).

Soak-тест не про пик, а про время: та же умеренная нагрузка держится часами. Так ловят проблемы, невидимые в коротком прогоне: рост потребления памяти, переполнение логов, исчерпание пула соединений.

На практике границы размываются: стресс переходит в объемный, объемный — в пиковый. Поэтому вид теста определяют не названием, а конкретной целью и профилем нагрузки.

Инструменты нагрузочного тестирования

Популярные инструменты на 2026 год и когда какой брать:

Инструмент Язык сценария Когда удобен
k6 (Grafana) JavaScript / TypeScript Скрипт как код, дружит с CI/CD, встроенные перцентили и пороги
JMeter (Apache) GUI + XML, скрипты на Groovy Богатый GUI, много протоколов, знаком многим командам
Locust Python Сценарии на Python, гибкая логика поведения пользователей
Gatling Scala / Java / Kotlin / JS / TS Высокая производительность на одну машину, наглядные отчеты

Выбор зависит от задачи, а не от «лучшего» инструмента. Если команда пишет на JavaScript и держит тесты в репозитории рядом с кодом — логичен k6. Если сценарии удобнее описывать на Python — Locust. Если нужен графический интерфейс без программирования — JMeter.

Как построить сценарий: пример на k6

Сценарий нагрузочного теста описывает, кто и как обращается к системе: сколько виртуальных пользователей (VU), как они разгоняются, что делают и какие пороги считаются провалом.

Ниже — минимальный рабочий сценарий на k6. Он разгоняет нагрузку до 50 виртуальных пользователей, держит минуту и плавно снижает. В качестве цели взят публичный эхо-сервис httpbin.org, чтобы пример можно было запустить без своего бэкенда.

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 }, // разгон до 50 VU
    { duration: '1m', target: 50 },  // удержание нагрузки
    { duration: '30s', target: 0 },  // плавный спад
  ],
  thresholds: {
    // тест провален, если ошибок больше 1%
    http_req_failed: ['rate<0.01'],
    // или если p95 > 500 мс, p99 > 800 мс
    http_req_duration: ['p(95)<500', 'p(99)<800'],
  },
};

export default function () {
  const res = http.get('https://httpbin.org/get');
  check(res, {
    'статус 200': (r) => r.status === 200,
  });
  sleep(1); // пауза между запросами одного пользователя
}

Запуск — командой в терминале:

k6 run script.js

По завершении k6 печатает сводку по метрикам: http_reqs (сколько запросов и RPS), http_req_duration со средним и перцентилями p(95)/p(99), http_req_failed (доля ошибок). Конкретные числа зависят от вашей сети и от того, что за система под нагрузкой, но структура сводки постоянна.

Главное — блок thresholds. Пороги превращают тест в проверку с вердиктом: если p95 вышел за 500 мс или ошибок стало больше 1%, k6 завершится с ненулевым кодом. Это и позволяет встроить нагрузочный тест в CI/CD и не пропустить регрессию производительности.

Частая ошибка новичков — убрать sleep() и разогнать сотни VU с одной машины. Тогда упирается сам генератор нагрузки (100% CPU на машине с k6), а не тестируемая система, и цифры получаются ложными:

level=warning msg="Executor is unable to keep up ..."

Правильно — следить за нагрузкой на самой машине-генераторе, держать реалистичные паузы между запросами и при нехватке ресурсов распределять нагрузку на несколько агентов.

Как проектировать нагрузочный тест: короткий алгоритм

  1. Сформулировать цель и требования в числах: целевой RPS, допустимый p95, максимальная доля ошибок.
  2. Выбрать вид теста под цель (load для проверки штатной нагрузки, stress для поиска предела, soak для выносливости).
  3. Подготовить среду, близкую к боевой по конфигурации, и не тестировать прод вслепую.
  4. Описать сценарий: профиль разгона, действия пользователя, пороги.
  5. Прогнать и снять метрики: throughput, latency (перцентили), error rate, а также ресурсы серверов.
  6. Найти узкое место, внести правку, повторить прогон и сравнить с предыдущим.

Выводы

  • Нагрузочное тестирование отвечает на вопрос «быстро и стабильно ли под нагрузкой», а не «правильно ли работает» — это задача функциональных тестов.
  • Три базовые цели: проверить поведение под нагрузкой, найти узкие места, определить предел.
  • Мерить нужно throughput (RPS), latency через перцентили p95/p99 (не среднее) и error rate.
  • Load держит ожидаемую нагрузку, stress превышает предел, soak растягивает нагрузку во времени — это разные тесты под разные вопросы.
  • Сценарий — это код: профиль нагрузки плюс пороги (thresholds), которые дают тесту вердикт и позволяют встроить его в CI/CD.

Где применяется / связь с практикой

Нагрузочное тестирование — часть работы инженера по тестированию и QA-автоматизатора: без него нельзя обещать, что сервис переживет распродажу или рассылку. На практике специалист описывает сценарии кодом, снимает метрики, находит узкое место вместе с разработчиками и повторяет прогон после правки.

Освойте тему на практике

Разобраться с инструментами (k6, JMeter, Locust), метриками и построением сценариев на реальных задачах помогает курс QA-инженер в Otus. Посмотреть формат и темы вживую можно на бесплатных открытых уроках Otus — там разбирают практику тестирования и отвечают на вопросы.

FAQ

Чем нагрузочное тестирование отличается от стресс-тестирования?
Нагрузочный (load) тест проверяет систему на ожидаемой штатной нагрузке и в норме проходит без ошибок. Стресс-тест сознательно превышает предел, чтобы увидеть точку отказа и характер деградации.

Почему смотрят p95 и p99, а не среднее время ответа?
Среднее сглаживает медленные ответы: пара быстрых замеров маскирует хвост из медленных. Перцентили показывают, что чувствуют самые «невезучие» 5% и 1% пользователей, а именно этот хвост портит опыт.

Можно ли гонять нагрузочные тесты сразу на проде?
Лучше на среде, близкой к боевой по конфигурации. Тесты на проде возможны, но требуют аккуратности: ограничения по времени и объему, изоляция тестовых данных, согласование с командой и план отката, иначе можно уронить живой сервис.

OTUS Журнал