Performance Testing: k6
k6 — open-source инструмент нагрузочного тестирования от Grafana Labs, скрипты пишутся на JavaScript и запускаются как бинарный файл, генерируя тысячи виртуальных пользователей.
Зачем нужно
Функциональные тесты не покажут, что API падает при 500 одновременных запросах. k6 позволяет найти узкие места производительности до того, как их найдут реальные пользователи. Скрипты пишутся на знакомом JavaScript, что снижает порог входа для разработчиков.
Где используется
- Load testing: проверка поведения при ожидаемой нагрузке
- Stress testing: поиск точки отказа системы
- Spike testing: поведение при резком росте трафика
- Smoke testing производительности: быстрая проверка что ничего не сломалось после деплоя
Основной контент
Установка
# macOS
brew install k6
# Windows (Chocolatey)
choco install k6
# Docker
docker run --rm -i grafana/k6 run - <script.js
Базовый скрипт
// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10, // 10 виртуальных пользователей
duration: '30s', // 30 секунд
};
export default function {
const res = http.get('https://api.example.com/users');
check(res, {
'статус 200': (r) => r.status === 200,
'время ответа < 500ms': (r) => r.timings.duration < 500,
'тело не пустое': (r) => r.body.length > 0,
});
sleep(1); // пауза 1 сек между итерациями
}
Профили нагрузки (stages)
export const options = {
stages: [
{ duration: '30s', target: 20 }, // плавный рост до 20 VU
{ duration: '1m', target: 20 }, // держим 20 VU 1 минуту
{ duration: '10s', target: 0 }, // плавный спад
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% запросов < 500ms
http_req_failed: ['rate<0.01'], // менее 1% ошибок
},
};
Тестирование POST с данными
import http from 'k6/http';
import { check } from 'k6';
export default function {
const payload = JSON.stringify({ email: 'test@example.com', password: 'pass' });
const params = { headers: { 'Content-Type': 'application/json' } };
const res = http.post('https://api.example.com/auth/login', payload, params);
check(res, {
'вход успешен': (r) => r.status === 200,
'получен токен': (r) => JSON.parse(r.body).token !== undefined,
});
}
Запуск и вывод
k6 run load-test.js
# Вывод метрик
# ✓ статус 200 [ 100% ]
# ✓ время ответа < 500ms [ 98% ]
#
# http_req_duration: avg=234ms min=102ms med=210ms max=1.2s p(90)=420ms p(95)=480ms
# http_reqs: 3240 (108/s)
Частые ошибки
- Запуск против production — нагрузочный тест на реальном production может положить сервис; используй staging
- Нет thresholds — без порогов k6 не вернёт exit code 1 при превышении лимитов; CI не поймает деградацию
- sleep(0) или нет sleep — без паузы VU генерирует максимальную нагрузку; это стресс-тест, а не реалистичный load
- Не учёт данных — все VU используют одинаковый email; реалистичный тест использует уникальные данные через
__VUпеременную