Добавить в корзинуПозвонить
Найти в Дзене
Анастасия Софт

Пишем читаемые и повторно используемые тесты в k6 с модулями

Привет, друг! Если ты уже знаком с основами нагрузочного тестирования в k6 и хочешь вывести свои скрипты на новый уровень — читай дальше. Сегодня мы поговорим о том, как создавать читаемые, повторно используемые и масштабируемые тесты с использованием ES6-модулей в k6. Представь, что ты пишешь тесты, которые: Модули помогают достичь всего этого. В k6 поддерживаются ES6-модули, что позволяет организовывать код по принципу "одна ответственность — один файл". Для начала убедимся, что у нас всё готово для работы с модулями. 3. Настройка config.js:// config.js
export const baseUrl = 'https://example.com';
export const thresholds = {
http_req_duration: ['p(95)<500'],
}; Создадим модуль для логина. // tests/login.js
import http from 'k6/http';
import { check } from 'k6';
import { baseUrl } from '../config.js';
export function login(username, password) {
const res = http.post(`${baseUrl}/login`, { username, password });
check(res, {
'login successful': (r) => r.status === 200,
});
Оглавление

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

🧩 Зачем нам модули?

Представь, что ты пишешь тесты, которые:

  • Легко поддерживаются: изменения в одном месте не ломают всё остальное.
  • Повторно используются: один и тот же код можно использовать в разных тестах.
  • Масштабируются: легко добавлять новые сценарии без переписывания старых.

Модули помогают достичь всего этого. В k6 поддерживаются ES6-модули, что позволяет организовывать код по принципу "одна ответственность — один файл".

🛠 Установка и настройка

Для начала убедимся, что у нас всё готово для работы с модулями.

  1. Устанавливаем k6: скачай и установи k6 с официального сайта.
  2. Создаём структуру проекта:my-k6-tests/
Создаём структуру проекта:my-k6-tests/
Создаём структуру проекта:my-k6-tests/

3. Настройка config.js:// config.js
export const baseUrl = 'https://example.com';
export const thresholds = {
http_req_duration: ['p(95)<500'],
};

📦 Пример 1: Модуль с функцией логина

Создадим модуль для логина.

// tests/login.js
import http from 'k6/http';
import { check } from 'k6';
import { baseUrl } from '../config.js';

export function login(username, password) {
const res = http.post(`${baseUrl}/login`, { username, password });
check(res, {
'login successful': (r) => r.status === 200,
});
return res.json('token');
}

🛒 Пример 2: Модуль для оформления заказа

Теперь модуль для оформления заказа.

// tests/checkout.js
import http from 'k6/http';
import { check } from 'k6';
import { baseUrl } from '../config.js';

export function checkout(token, cart) {
const res = http.post(
`${baseUrl}/checkout`,
JSON.stringify(cart),
{ headers: { Authorization: `Bearer ${token}` } }
);
check(res, {
'checkout successful': (r) => r.status === 200,
});
return res.json('orderId');
}

🧪 Пример 3: Основной тестовый сценарий

Теперь соберём всё вместе в основном тесте.

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import { baseUrl, thresholds } from '../config.js';

export const options = {
thresholds: thresholds,
};

export default function () {
const token = login('user', 'password');
const cart = [{ productId: 1, quantity: 2 }];
checkout(token, cart);
}

🛠 Пример 4: Использование переменных окружения

Иногда полезно настраивать поведение тестов через переменные окружения.

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import { baseUrl, thresholds } from '../config.js';

export const options = {
thresholds: thresholds,
};

export default function () {
const username = __ENV.USERNAME || 'user';
const password = __ENV.PASSWORD || 'password';
const token = login(username, password);
const cart = [{ productId: 1, quantity: 2 }];
checkout(token, cart);
}

Запуск:

k6 run -e USERNAME=admin -e PASSWORD=secret tests/main.js

📦 Пример 5: Использование внешних библиотек

k6 поддерживает использование внешних библиотек через CDN.

// tests/main.js
import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

export default function () {
console.log(randomItem([1, 2, 3]));
}

🧪 Пример 6: Тестирование с использованием сценариев

Сценарии позволяют моделировать различные нагрузки.

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import { baseUrl, thresholds } from '../config.js';

export const options = {
scenarios: {
checkout: {
executor: 'ramping-vus',
stages: [
{ duration: '1m', target: 10 },
{ duration: '1m', target: 20 },
{ duration: '1m', target: 30 },
],
},
},
thresholds: thresholds,
};

export default function () {
const token = login('user', 'password');
const cart = [{ productId: 1, quantity: 2 }];
checkout(token, cart);
}

🧪 Пример 7: Тестирование с использованием групп

Группы помогают структурировать тесты.

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import { baseUrl, thresholds } from '../config.js';

export const options = {
thresholds: thresholds,
};

export default function () {
group('User Login', () => {
const token = login('user', 'password');
});

group('Checkout', () => {
const cart = [{ productId: 1, quantity: 2 }];
checkout(token, cart);
});
}

🧪 Пример 8: Тестирование с использованием чеков

Чеки позволяют проверять ответы.

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import { baseUrl, thresholds } from '../config.js';

export const options = {
thresholds: thresholds,
};

export default function () {
const token = login('user', 'password');
const cart = [{ productId: 1, quantity: 2 }];
const orderId = checkout(token, cart);

check(orderId, {
'orderId is not null': (id) => id !== null,
});
}

🧪 Пример 9: Использование сессий и хранения состояния

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

Создадим модуль session.js:

// tests/session.js
let session = {};

export function set(key, value) {
session[key] = value;
}

export function get(key) {
return session[key];
}

Применим его в основном тесте:

// tests/main.js
import { login } from './login.js';
import { checkout } from './checkout.js';
import * as session from './session.js';

export default function () {
const token = login('user', 'password');
session.set('token', token);

const cart = [{ productId: 1, quantity: 2 }];
const orderId = checkout(session.get('token'), cart);
console.log(`Order placed with ID: ${orderId}`);
}

📎 Такой подход позволяет эмулировать хранение состояния пользователя, особенно полезно при многошаговых сценариях.

🧪 Пример 10: Модуль для генерации случайных данных (faker)

Нам нужен способ генерировать данные пользователей или заказов. Давай напишем простой faker-модуль:

// tests/utils/faker.js
export function getRandomUsername() {
const id = Math.floor(Math.random() * 10000);
return `user_${id}`;
}

export function getRandomCart() {
const quantity = Math.floor(Math.random() * 5) + 1;
return [{ productId: 1, quantity }];
}

Применим в main.js:

import { login } from './login.js';
import { checkout } from './checkout.js';
import * as faker from './utils/faker.js';

export default function () {
const username = faker.getRandomUsername();
const token = login(username, 'password');
const cart = faker.getRandomCart();
const orderId = checkout(token, cart);
}

📦 Организация большого проекта (советы и структура)

Вот как может выглядеть хорошо организованный проект:

хорошо организованный проект
хорошо организованный проект

💡 Лучшие практики:

  • Разделяй по доменам (user, order, etc.)
  • Используй utils/ для вспомогательных функций
  • Храни config.js для глобальных переменных
  • Не бойся использовать SharedArray для данных и __ENV для гибкости

📈 Бонус: логгирование и кастомная аналитика

Добавим простой логгер:

// utils/logger.js
export function log(title, value) {
console.log(`[${title}] ${JSON.stringify(value)}`);
}

И используем:

import * as logger from './utils/logger.js';

export default function () {
const token = login('user', 'password');
logger.log('Token', token);

const cart = [{ productId: 1, quantity: 2 }];
const orderId = checkout(token, cart);
logger.log('Order ID', orderId);
}

🧠 Заключение

Поздравляю, ты прошёл погружение в модули в k6, научился:

  • Делить код на логические части
  • Повторно использовать функциональность
  • Организовывать тестовый проект по всем канонам разработки

Теперь твои тесты будут читабельные, поддерживаемые и масштабируемые. А твои коллеги скажут: «О, кто-то тут явно знает, что делает».