Стенды, безопасность и базовая линия
📋 Вы точно готовы?
Обязательные знания:
- ✅ Урок 02: понимаете типы тестов (smoke/load/stress) и требования к стендам
- ✅ Базовое знание окружений: dev, stage, production
- ✅ Понимание концепции CI/CD pipelines
Опционально:
- Опыт с Docker/Kubernetes для запуска тестовых окружений
- Доступ к pre-prod или staging окружению вашего приложения
⏱️ Estimated time:
- Чтение + кейс: 10 минут
- Практика (sanity-check + baseline): 10 минут
- Итого: 20 минут
Выбор стенда
- Dev — только быстрый feedback для разработчика. Без смысла гонять RPS.
- Stage — для smoke/load на флоу, но часто урезаны ресурсы и отключены сторонние интеграции.
- Pre-prod — зеркальный прод по конфигу, сюда выносим stress/spike/soak. Если его нет — делайте prod с feature flag и ограничением трафика.
- Prod — допускается для smoke/breakpoint перед big sale, но только с feature flag, отключенными платёжными действиями и уведомлениями пользователям.
Никогда не бейте 3rd-party (платежи, CRM, рассылки) без sandbox или мока. Реальные смс/платежи во время теста — быстрый способ потерять деньги и друзей.
Проверка, что уперлись не в генератор
- Смотрите на CPU/RAM/Network машины с k6. Если CPU > 85% или
dropped_iterationsпоявляется — это генератор, а не сервис. - При
constant-arrival-rateдержитеmaxVUsс запасом. Еслиhttp_req_sending/receivingрастут, а сервис молчит — вероятно, уперлись в клиентскую сеть. - Для больших тестов используйте отдельную машину/VM только под k6, не запускайте браузеры/IDE рядом.
- Отражайте факт использования ramp-up (warmup) в сценарии, чтобы избежать cold start в сервисах.
Подготовка данных и безопасности
- Идемпотентность: предусмотреть очистку (teardown) или работу на тестовых ресурсах.
- Данные платежей/PII: только synthetic или маскированные, прокинутые через
SharedArray/env переменные. - Feature flags: отключаем побочные эффекты (письма, webhooks), включаем кэширование, которое будет в проде.
- Управление тестовыми данными: шаблоны пользователей/заказов в фикстурах, уникальные id на итерацию (
__VU+__ITER), периодический reset снапшота БД и cleanup jobs после теста, чтобы параллельные запуски не конфликтовали.
Baseline стенда
- Фиксируем: версии сервисов, конфиги (лимиты connection pool, cache TTL), объем данных в БД, включенные интеграции, дата создания снапшота.
- Перед тестом — здоровье стенда: алертов нет, бэкапы/cron jobs отключены, автоскейлер в нужном режиме.
- После теста — сохраняем k6 summary + ссылку на Grafana/Prometheus + короткий вывод: «узкое место — очередь в payment-service (latency p99: +250ms), CPU 40%».
Используем k6 с опорой на стенд
// sanity-check.js — быстрый прогонищик стенда перед основным тестом
import http from "k6/http";
import { check } from "k6";
export const options = {
vus: 3,
duration: "2m",
thresholds: {
http_req_failed: ["rate<0.02"],
http_req_duration: ["p(95)<800"],
},
};
export default function () {
const res = http.get(`${__ENV.BASE_URL}/health`);
check(res, {
"status ok": (r) => r.status === 200,
"has build id": (r) => r.json("buildId") !== undefined,
});
}Запускаем sanity перед load/stress, чтобы не тратить время на некорректный стенд. Summary sanity-теста кладем рядом с основным, baseline обновляем только при стабильном состоянии.
📊 Реальный кейс: Финтех-стартап и "тест на production"
Контекст: Стартап в сфере lending (выдача микрозаймов) запланировал маркетинговую кампанию с участием знаменитости → прогноз 50x traffic spike за 2 часа.
Проблема: Единственный стенд — production. Pre-prod не существовал, staging работал на 1/10 ресурсов и без реальных данных.
Что пошло не так (первая попытка):
-
Запустили k6 "stress test" на staging:
- ✅ Выдержал 200 RPS (цель: 2000 RPS)
- ❌ CPU staging-сервера: 95% (vs 25% на production при 40 RPS)
- ❌ БД staging: 500K записей (production: 45M)
- Вывод: Staging не репрезентативен → цифры бесполезны
-
Решили протестировать production:
- ⚠️ Включили feature flag
load_test_mode=true - ⚠️ Настроили mock для SMS-провайдера... но забыли про webhook в CRM
- 🔴 Инцидент: k6 создал 15K "заявок на займы" → CRM отправил sales team 15K лидов
- 🔴 Sales manager: "Мы весь день обзванивали несуществующих клиентов!"
- ⚠️ Включили feature flag
-
Потери:
- 8 часов работы sales team ($3K)
- Cleanup базы: 4 часа DBA времени
- Репутационный риск: клиенты получили email "Ваша заявка одобрена" (baч spam filters, но всё равно)
Что сделали правильно (вторая попытка):
-
Создали minimal pre-prod за 5 дней:
- Kubernetes namespace с production-конфигом, но 50% ресурсов
- Snapshot production БД (45M записей) → восстановили на pre-prod
- Настроили mocks для: SMS, CRM webhooks, платежные gateway
- Feature flag
environment=pre-prod→ отключает email/push уведомления
-
Провели sanity-check перед stress:
// sanity-preprod.js export default function () { const res = http.post(`${BASE_URL}/api/loan/apply`, payload); check(res, { "no real SMS sent": (r) => r.json("sms_sent") === false, "no CRM webhook": (r) => r.json("crm_notified") === false, "loan created in DB": (r) => r.json("loan_id") !== null, }); } -
Stress-тест на pre-prod:
- ✅ Выдержали 2500 RPS (запас 25% сверх прогноза)
- ✅ p95 loan application: 420ms (SLO: <500ms)
- ✅ Нашли bottleneck: credit scoring service (external API rate limit 1000 req/s) → добавили circuit breaker
-
Проверили генератор k6:
- CPU k6-машины: 68% (норма)
dropped_iterations: 0- Network saturation: нет
Результат маркетинговой кампании:
- Peak traffic: 2200 RPS (в прогнозе 2000)
- p95 latency: 465ms
- Error rate: 0.12%
- Zero инцидентов, conversion rate +18% vs обычного дня
- Sales team обработал реальные лиды, не тестовые
ROI:
- Стоимость pre-prod setup: $15K (Kubernetes + snapshot restore + 5 дней работы)
- Избежали: повторный инцидент ($10K+ потери времени + репутация), potential downtime во время кампании ($200K убытков по конверсии)
- ROI: 14x
War story: После инцидента с CRM, CTO ввел правило: "Любой тест на production требует checklist из 12 пунктов + подпись двух senior инженеров". Через месяц всё равно создали pre-prod, потому что checklist занимал больше времени, чем поднять стенд.
Урок: "У нас нет pre-prod" — это не оправдание, а технический долг с конкретной ценой. Baseline на неподходящем стенде — это иллюзия безопасности, хуже, чем отсутствие тестов. Лучше 2 недели на minimal pre-prod, чем годы жизни без уверенности в production.
✅ Чек-лист завершения урока
После этого урока вы должны уметь:
Выбор стенда:
- Понимать разницу между dev/stage/pre-prod/prod для нагрузочного тестирования
- Знать, какой стенд выбрать для каждого типа теста (smoke/load/stress/soak)
- Понимать риски тестирования на production и как их минимизировать
Безопасность и данные:
- Настроить feature flags для отключения побочных эффектов (emails, SMS, webhooks)
- Подготовить тестовые данные (synthetic или маскированные)
- Убедиться, что 3rd-party интеграции отключены или используют sandbox
Проверка генератора:
- Мониторить CPU/RAM генератора k6 (должно быть < 85%)
- Проверять метрику
dropped_iterations(должна быть 0) - Понимать, когда bottleneck в генераторе, а когда в сервисе
Baseline:
- Задокументировать baseline: версии, конфиг, объем данных, дата
- Запустить sanity-check перед основным тестом
- Сохранить summary.json + ссылку на Grafana dashboard
Практическое задание:
- Создайте sanity-check.js для вашего проекта (как в примере выше)
- Запустите на staging и зафиксируйте baseline
- Запишите: версия сервиса, конфиг БД, дата создания snapshot
Если чек-лист пройден — вы готовы к уроку 04: научимся работать с тест-данными и параметризацией.
🎯 Что дальше
Следующий урок: Урок 04: Тест-данные и параметризация
Что вы изучите:
- Как генерировать реалистичные тест-данные для ваших сценариев
- SharedArray для эффективного использования памяти
- Управление пулами тестовых пользователей и сущностей
- Parametrization patterns для масштабируемых тестов
⏱️ Estimated time: 20 минут
Связанные уроки:
- Урок 05: Первый smoke-тест — применим данные в реальном тесте
- Урок 07: Traffic modeling — realistic user journeys с данными