k6: нагрузочное тестирование как система
8 / 1747%
Продвинутая разработка сценариев на JavaScript в k6
25 минут
Модульность и архитектура директории
- Организуйте проект как код:
/tests
/scenarios
reader.js
buyer.js
admin.js
/lib
auth.js
http-client.js
/data
users.json
products.json
main.js
k6.config.js- Сценарии — в
/scenarios, общие утилиты — в/lib, фикстуры — в/data. Главный файл только склеивает сценарии, опции и метрики. - Общие константы и данные — в
config.jsиSharedArray(после сериализации!).
// flows/buyer.js
import http from "k6/http";
import { check, sleep } from "k6";
export function buyer(baseUrl, user) {
const login = http.post(`${baseUrl}/api/login`, user);
check(login, { login: (r) => r.status === 200 });
const add = http.post(`${baseUrl}/api/cart`, { sku: "SKU-1", qty: 1 });
check(add, { cart: (r) => r.status === 200 });
sleep(1 + Math.random());
}// main.js
import { SharedArray } from "k6/data";
import { buyer } from "./flows/buyer.js";
const users = new SharedArray("users", () =>
JSON.parse(open("./fixtures/users.json"))
);
export default function () {
const user = users[__ITER % users.length];
buyer(__ENV.BASE_URL, user);
}Внешние зависимости
- Используйте
open()+ bundler (esbuild/webpack) для локальных JS/JSON. K6 не поддерживает dynamic import с сети. - Для хелперов на TypeScript — собирайте в JS перед запуском.
- Проверяйте размер бандла: лишние библиотеки (lodash целиком) увеличивают потребление памяти VU.
Синхронный API и отсутствие async/await
- k6 исполняет JS синхронно; «параллельность» достигается через VU и
http.batch(). - async/await нет: промисы не ждутся. Параллельность — через batch или несколько VU.
sleep()— моделирует think time, а не «зло». Но избегайте long sleep внутри VU, если цель — удерживать RPS; лучше больше VU и небольшой sleep (реалистичный тайминг).- Никогда не держите долгие синхронные вычисления внутри VU (JSON.stringify мегаструктур) — это съест CPU генератора. Тяжелые препроцессы вынесите в
setup.
Отладка и трассировка
console.logс префиксами VU/ITER:console.log('[vu=' + __VU + ' iter=' + __ITER + ']', res.status);.--http-debug=fullили--http-debug=tracingдля сети (только на малом VU).- Структурированные логи: создайте объект с
vu,iter,statusи передайте вJSON.stringify()→ потом парс в Loki/ELK. - Локально: уменьшайте
vusдо 1–2 и включайтеthrowв checks (handleSummaryможет выводить детали). - Для сложных сценариев добавляйте флаги
__ENV.DEBUGи условные логи.
Работа с данными
SharedArrayзагружается один раз в init-контексте — избегайте обращения к файлам внутри VU.- Генерация уникальных id:
Date.now() + '-' + __VU + '-' + __ITER; пулы данных — через циклы поSharedArray. - Очистка: teardown, отдельные cleanup-скрипты, метки
test-run-idна сущностях для массового удаления.
Классы и сложные структуры
- Можно использовать классы для моделей, но держите их сериализуемыми:
class Cart {
constructor(baseUrl) {
this.baseUrl = baseUrl;
}
add(sku, qty = 1) {
return http.post(`${this.baseUrl}/api/cart`, { sku, qty });
}
}
export default function () {
const cart = new Cart(__ENV.BASE_URL);
const res = cart.add("SKU-1");
check(res, { added: (r) => r.status === 200 });
}- Избегайте хранения больших массивов в свойствах экземпляров — каждая VU копирует их.
Инструменты качества
- ESLint/Prettier для тестов — уменьшает количество «битых» сценариев.
- TypeScript типы из k6 для автодополнения (
npm i -D @types/k6). - Юнит-тесты утилит (функции построения данных) — можно гонять
vitest/jestотдельно от k6.
✅ Чек-лист завершения урока
После этого урока вы должны уметь:
Модульная архитектура:
- Организовать тесты в папки:
/scenarios,/lib,/data - Вынести общие функции в
/lib(auth.js, http-client.js) - Создать переиспользуемые сценарии в
/scenarios - Главный файл (main.js) только склеивает сценарии и опции
Работа с данными:
- Использовать
SharedArrayдля загрузки данных один раз - Знать, что
open()работает только в init-контексте - Избегать обращений к файлам внутри VU-кода
Особенности JavaScript в k6:
- Понимать, что нет async/await — только синхронный код
- Использовать
http.batch()для параллельных запросов в VU - Знать, что
sleep()— это нормально, а не зло - Избегать тяжелых вычислений в VU (вынести в setup)
Отладка:
- Использовать
console.logс префиксами VU/ITER - Знать флаг
--http-debug=fullдля сетевой диагностики - Уменьшать VU до 1-2 для локальной отладки
- Добавлять условные логи через
__ENV.DEBUG
Качество кода:
- Использовать классы для моделей (Cart, User, etc.)
- Настроить ESLint/Prettier для тестов
- Добавить TypeScript типы для автодополнения (
@types/k6)
Практическое задание:
- Рефакторите ваши тесты в модульную структуру
- Вынесите общие функции (login, addToCart) в
/lib - Создайте
SharedArrayдля users.json и products.json - Убедитесь, что тесты запускаются без изменения результатов
Если чек-лист пройден — переходите к уроку 09: привяжем метрики и thresholds к реальным SLO.