Нагрузочное тестирование
Mockarty включает встроенный движок нагрузочного тестирования, позволяющий писать тесты на JavaScript для любого поддерживаемого протокола: HTTP, gRPC, SOAP, GraphQL, WebSocket, SSE, Kafka, RabbitMQ, MCP, SMTP и других.

Скрипты поддерживают синтаксис k6 ESM (import http from 'k6/http'), поэтому разработчики, знакомые с k6, могут писать тесты в аналогичном стиле. Примечание: Mockarty использует собственную систему модулей (mockarty/http, mockarty/grpc и т.д.), которая предоставляет подмножество глобальных функций k6 (check, sleep, group, fail), но не является полным рантаймом k6 – продвинутые возможности k6 (k6/browser, k6/execution, расширения k6) недоступны.
URL-адреса в примерах: Во всех примерах используется
localhost:5770как адрес Mockarty по умолчанию. Если ваш экземпляр работает на удалённом сервере, заменитеlocalhost:5770на реальный адрес (например,https://mockarty.company.comилиhttp://192.168.1.50:5770). Подробнее — в разделе Полезные функции и советы.
Что такое нагрузочное тестирование?
Нагрузочное тестирование (performance testing) — это практика имитации реалистичного пользовательского трафика к вашему приложению для измерения его поведения под нагрузкой. В отличие от функциональных тестов, проверяющих корректность, нагрузочные тесты отвечают на вопросы: “Сколько пользователей выдержит мой API до того, как время ответа станет неприемлемым?” и “Переживёт ли мой сервис всплеск трафика в день запуска?”
Прежде чем углубиться, вот ключевые термины, которые встретятся в этом руководстве:
| Термин | Определение |
|---|---|
| Виртуальный пользователь (VU) | Имитируемый пользователь, многократно выполняющий ваш тестовый скрипт. Если вы зададите vus: 50, Mockarty создаст 50 независимых “пользователей”, делающих запросы одновременно. |
| p95 задержка | 95-й перцентиль времени ответа. Означает, что 95% всех запросов выполнились быстрее этого значения. Например, если p95 равен 200 мс, то лишь 5% запросов заняли более 200 мс. Эта метрика предпочтительнее средних значений, поскольку отражает опыт самых медленных пользователей. |
| APDEX | Application Performance Index — отраслевой стандарт оценки от 0 до 1, переводящий время ответа в рейтинг удовлетворённости пользователей. Оценка выше 0.94 — “Отлично”, ниже 0.50 — “Неприемлемо”. Подробнее в разделе Оценка APDEX. |
| Пороги (Thresholds) | Правила прохождения/провала, которые вы задаёте для теста. Например, 'p(95) < 500' означает, что тест проваливается, если 95-й перцентиль времени ответа превышает 500 мс. Пороги позволяют блокировать CI/CD-пайплайны по производительности. |
| Пропускная способность (Throughput) | Количество запросов, обрабатываемых вашей системой в секунду (часто записывается как RPS — requests per second). |
Зачем проводить нагрузочное тестирование API?
Проблемы производительности редко проявляются во время разработки. Один эндпоинт, отвечающий за 5 мс без нагрузки, может деградировать до 2 секунд при одновременном обращении 500 пользователей. Нагрузочное тестирование помогает:
- Выявлять узкие места до попадания в продакшен. Найти эндпоинт, запрос к базе данных или внешнюю зависимость, которая ломается под нагрузкой.
- Устанавливать базовые показатели. Знать пропускную способность (запросов/сек) и перцентили задержки (p50, p95, p99), чтобы отслеживать регрессии.
- Проверять SLA. Задавать пороги прохождения/провала, например “p95 задержки должен быть менее 200 мс”, и автоматически помечать сборки, нарушающие их.
- Планировать мощности. Определять, сколько одновременных пользователей выдержит ваша инфраструктура перед необходимостью масштабирования.
- Тестировать отказоустойчивость. Моделировать всплески трафика, медленных потребителей и лавины ошибок для проверки корректной деградации.
Обзор движка скриптов

Движок производительности выполняет JavaScript-скрипты с использованием среды выполнения goja. Скрипты внутренне используют паттерн модулей CommonJS. Mockarty автоматически конвертирует синтаксис k6 ESM (import http from 'k6/http') в нативный формат require('mockarty/http'). Основные функции k6 (check, sleep, group, fail) и конструкторы метрик (Counter, Trend, Rate, Gauge) доступны как глобальные переменные.
Ключевые концепции
| Концепция | Описание |
|---|---|
| Итерация | Одно полное выполнение функции default. VU выполняет итерации непрерывно до окончания теста. |
| Длительность | Время выполнения теста. По умолчанию 30 секунд, если не указано иное. |
| Этапы (Stages) | Временные фазы, увеличивающие и уменьшающие количество VU (или RPS), обеспечивающие реалистичные паттерны трафика. |
| Режим RPS | Вместо фиксированного числа VU вы задаёте целевое количество запросов в секунду, а движок автоматически регулирует число VU для его поддержания. |
| Критерии прерывания | Условия, вызывающие досрочное завершение теста (например, частота ошибок выше 50% в течение 30 секунд). |
Автоопределение формата скрипта
Mockarty автоматически определяет три формата скриптов и конвертирует их:
- Нативный Mockarty —
require('mockarty/http')сmodule.exports.default - k6 ESM —
import http from 'k6/http'сexport default function - Устаревший mk/pm — паттерны
mk.http.get(...)иmk.test(...)
Вы можете писать в любом удобном формате. Движок конвертирует всё во внутренний формат CommonJS перед выполнением.
Написание первого нагрузочного теста
Вот минимальный HTTP-тест нагрузки:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10,
duration: '30s',
};
export default function () {
const res = http.get('https://api.example.com/users');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
Или эквивалент в нативном формате Mockarty:
var http = require('mockarty/http');
module.exports.options = {
vus: 10,
duration: '30s',
};
module.exports.default = function () {
var res = http.get('https://api.example.com/users');
check(res, {
'status is 200': function (r) { return r.status === 200; },
'response time < 500ms': function (r) { return r.timings.duration < 500; },
});
sleep(1);
};
Оба скрипта дают идентичные результаты. Движок автоматически конвертирует импорты k6.
Пошаговый разбор
- Импорт модулей — загрузите HTTP-модуль (и другие при необходимости).
- Определение параметров — задайте число VU, длительность, этапы, пороги.
- Написание функции default — это ваша итерация. Каждый VU вызывает её в цикле.
- Добавление проверок — валидируйте статус ответа, тело, время.
- Добавление sleep — имитируйте время обдумывания пользователя между запросами (в секундах).
Параметры теста
Параметры управляют выполнением теста. Определяйте их как export const options (формат k6) или module.exports.options (нативный формат).
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
vus |
int |
1 |
Количество одновременных виртуальных пользователей. |
duration |
string |
"30s" |
Длительность теста (напр., "30s", "5m", "1h"). Формат длительности Go. |
iterations |
int |
0 (без ограничений) |
Общее число итераций по всем VU. Тест останавливается при достижении. |
rps |
int |
0 (режим VU) |
Целевое число запросов в секунду. Движок автоматически регулирует число VU. |
maxVUs |
int |
200 |
Предельное количество VU в режиме RPS. Предотвращает неконтролируемое масштабирование. |
stages |
[]Stage |
[] |
Временные этапы нарастания VU или RPS. Переопределяет vus и duration. |
thresholds |
map |
{} |
Критерии прохождения/провала, оцениваемые по итоговым метрикам. |
abortCriteria |
[]Criterion |
[] |
Условия досрочного завершения теста. |
Определение этапов
Каждый этап имеет длительность и целевое значение:
export const options = {
stages: [
{ duration: '30s', target: 20 }, // Нарастание до 20 VU за 30 сек
{ duration: '1m', target: 20 }, // Удержание 20 VU в течение 1 минуты
{ duration: '30s', target: 0 }, // Снижение до 0 VU за 30 сек
],
};
Движок линейно интерполирует количество VU между этапами.
Этапы RPS
Для управления на основе RPS используйте targetRPS вместо target:
export const options = {
maxVUs: 100,
stages: [
{ duration: '30s', targetRPS: 50 }, // Нарастание до 50 запр/сек
{ duration: '1m', targetRPS: 200 }, // Нарастание до 200 запр/сек
{ duration: '30s', targetRPS: 0 }, // Снижение
],
};
Движок использует пропорциональный контроллер с демпфированием для регулировки числа VU, избегая осцилляций. Изменения VU ограничены ±20% в секунду.
Режимы выполнения
Движок работает в одном из двух режимов:
- Режим производительности — несколько VU, сбор временных рядов, графики. Активен при
vus > 1,duration > 0, заданных этапах илиiterations > 0. - Функциональный режим — один VU, одна итерация, подробные результаты проверок. Активен, когда параметры производительности не заданы. Полезен для проверки корректности скрипта перед масштабированием.
Доступные модули
Mockarty предоставляет 14 встроенных модулей, охватывающих все поддерживаемые протоколы и распространённые утилиты.
mockarty/http
HTTP-клиент для тестирования REST API.
var http = require('mockarty/http');
// GET-запрос
var res = http.get('https://api.example.com/users');
// POST с JSON-телом и заголовками
var res = http.post('https://api.example.com/users',
JSON.stringify({ name: 'Alice', email: 'alice@example.com' }),
{ headers: { 'Content-Type': 'application/json' } }
);
// Другие методы
http.put(url, body, params);
http.patch(url, body, params);
http.del(url, params);
http.head(url, params);
http.options(url, params);
http.request('CUSTOM_METHOD', url, body, params);
Объект ответа:
| Поле | Тип | Описание |
|---|---|---|
status |
int |
HTTP-код статуса |
body |
string |
Тело ответа в виде строки |
json() |
function |
Парсинг тела как JSON |
headers |
object |
Заголовки ответа |
timings.duration |
float |
Длительность запроса в миллисекундах |
error |
string |
Сообщение об ошибке (пустое при успехе) |
Автоматические метрики: http_reqs (счётчик), http_req_duration (тренд), http_req_failed (частота), data_sent, data_received.
Нормализация маршрутов: URL автоматически нормализуются для отчётов по маршрутам. UUID-сегменты заменяются на {uuid}, числовые сегменты — на {id}. Пример: GET /users/42/orders становится GET /users/{id}/orders.
mockarty/grpc
gRPC-клиент с поддержкой серверной рефлексии.
var grpc = require('mockarty/grpc');
// Подключение с рефлексией (автоматическое обнаружение сервисов)
var client = grpc.connect('localhost:4770', {
reflect: true,
plaintext: true,
});
// Вызов унарного RPC
var res = client.invoke('mypackage.UserService/GetUser', {
user_id: '123',
}, {
headers: { 'authorization': 'Bearer token123' },
});
check(res, {
'gRPC status OK': function (r) { return r.status === 'OK'; },
'has user name': function (r) { return r.message.name !== ''; },
});
// Доступны тайминги
// res.timings.duration — длительность запроса в мс
client.close();
Параметры подключения:
| Параметр | Тип | Описание |
|---|---|---|
reflect |
bool |
Использовать серверную рефлексию для обнаружения сервисов. Обязательно. |
plaintext |
bool |
Отключить TLS (для локального тестирования). |
tls |
bool |
Включить TLS с системными сертификатами. |
Автоматические метрики: grpc_reqs (счётчик), grpc_req_duration (тренд), grpc_req_failed (частота).
mockarty/soap
Клиент SOAP/XML веб-сервисов.
var soap = require('mockarty/soap');
var res = soap.call('http://localhost:8080/soap', {
action: 'GetWeather',
body: '<GetWeatherRequest><City>London</City></GetWeatherRequest>',
headers: {
'X-Custom': 'value',
},
});
check(res, {
'SOAP status 200': function (r) { return r.status === 200; },
'has body': function (r) { return r.body.length > 0; },
});
Если тело ещё не обёрнуто в SOAP-конверт, модуль оборачивает его автоматически.
Автоматические метрики: soap_reqs (счётчик), soap_req_duration (тренд), soap_req_failed (частота).
mockarty/ws
WebSocket-клиент для тестирования двунаправленной коммуникации.
var ws = require('mockarty/ws');
var conn = ws.connect('ws://localhost:8080/ws', {
headers: { 'Authorization': 'Bearer token' },
});
// Отправка сообщения
conn.send(JSON.stringify({ type: 'subscribe', channel: 'orders' }));
// Отправка бинарных данных
conn.sendBinary('raw binary data');
// Получение сообщения (опциональный таймаут в секундах, по умолчанию 30)
var msg = conn.receive(5);
check(msg, {
'received message': function (m) { return m.length > 0; },
});
conn.close();
Автоматические метрики: ws_sessions (счётчик), ws_messages_sent (счётчик), ws_messages_received (счётчик), ws_connecting (тренд), ws_send_duration (тренд), ws_recv_duration (тренд), ws_connect_failed (частота).
mockarty/sse
Клиент Server-Sent Events.
var sse = require('mockarty/sse');
// Подключение и сбор событий
var events = sse.connect('http://localhost:8080/events', {
timeout: '10s', // Таймаут подключения
limit: 5, // Максимум событий для сбора (0 = без ограничений до таймаута)
headers: {
'Authorization': 'Bearer token',
},
});
check(events, {
'received events': function (e) { return e.length > 0; },
'first event has data': function (e) { return e[0].data !== ''; },
});
// Каждый объект события: { id, event, data, retry }
Автоматические метрики: sse_events_received (счётчик), sse_connecting (тренд), sse_connect_failed (частота).
mockarty/kafka
Продюсер и консюмер Apache Kafka. Mockarty работает с реальным кластером Kafka — он не эмулирует брокер. Подготовьте запущенный кластер (локальный docker-compose, dev-кластер или testcontainers) по адресу, который вы передаёте в brokers. Если брокер недоступен, скрипт сообщает об ошибках подключения, а метрики kafka_*_failed растут.
var kafka = require('mockarty/kafka');
// Создание продюсера
var producer = kafka.producer({
brokers: ['localhost:9092'],
});
// Отправка сообщений
producer.produce({
topic: 'orders',
messages: [
{ key: 'order-1', value: JSON.stringify({ amount: 99.99 }) },
{ key: 'order-2', value: JSON.stringify({ amount: 149.50 }) },
],
});
// Создание консюмера
var consumer = kafka.consumer({
brokers: ['localhost:9092'],
groupId: 'perf-test-group',
});
// Потребление сообщений
var messages = consumer.consume({
topic: 'orders',
limit: 10,
timeout: '5s',
});
check(messages, {
'consumed messages': function (m) { return m.length > 0; },
});
// Каждое сообщение: { key, value, topic, partition, offset }
Автоматические метрики: kafka_messages_produced (счётчик), kafka_messages_consumed (счётчик), kafka_produce_duration (тренд), kafka_consume_duration (тренд), kafka_produce_failed (частота).
mockarty/rabbitmq
Издатель и потребитель RabbitMQ. Mockarty работает с реальным экземпляром RabbitMQ — он не эмулирует брокер. Подготовьте запущенный RabbitMQ (локальный docker-compose, dev-инстанс или testcontainers) по AMQP-адресу, который вы передаёте в connect(). Если брокер недоступен, скрипт сообщает об ошибках подключения, а метрики rmq_*_failed растут.
var rabbitmq = require('mockarty/rabbitmq');
var conn = rabbitmq.connect('amqp://guest:guest@localhost:5672/');
// Публикация сообщения
conn.publish({
exchange: '',
routingKey: 'task_queue',
body: JSON.stringify({ task: 'process_order', orderId: '12345' }),
contentType: 'application/json',
});
// Потребление сообщений
var messages = conn.consume({
queue: 'task_queue',
limit: 5,
timeout: '10s',
});
check(messages, {
'received messages': function (m) { return m.length > 0; },
});
// Каждое сообщение: { body, routingKey, exchange, contentType }
conn.close();
Автоматические метрики: rmq_messages_published (счётчик), rmq_messages_consumed (счётчик), rmq_publish_duration (тренд), rmq_consume_duration (тренд), rmq_publish_failed (частота).
mockarty/mcp
MCP-клиент (Model Context Protocol) для тестирования MCP-серверов.
var mcp = require('mockarty/mcp');
var client = mcp.connect('http://localhost:8910/sse');
// Получение списка доступных инструментов
var tools = client.listTools();
// Вызов инструмента
var result = client.callTool('get_weather', {
city: 'London',
});
check(result, {
'no error': function (r) { return !r.isError; },
'has content': function (r) { return r.content && r.content.length > 0; },
});
// result.content = [{ type: "text", text: "..." }, ...]
// result.timings.duration — длительность в мс
client.close();
Автоматические метрики: mcp_reqs (счётчик), mcp_req_duration (тренд), mcp_req_failed (частота).
mockarty/redis
Redis-клиент с пулом соединений, разделяемым между VU.
var redis = require('mockarty/redis');
// Открытие соединения (по умолчанию использует переменную окружения MOCKARTY_REDIS_ADDR)
var client = redis.open('redis://localhost:6379/0');
// Строковые команды
client.set('user:1:name', 'Alice', 3600); // ключ, значение, ttl_секунды
var result = client.get('user:1:name'); // { value: "Alice", error: null }
client.incr('counter');
client.decr('counter');
// Хеш-команды
client.hset('user:1', 'email', 'alice@example.com');
var email = client.hget('user:1', 'email');
var all = client.hgetall('user:1');
// Команды списков
client.lpush('queue', 'item1', 'item2');
var item = client.rpop('queue');
var items = client.lrange('queue', 0, -1);
// Команды множеств
client.sadd('tags', 'golang', 'performance');
var members = client.smembers('tags');
var exists = client.sismember('tags', 'golang');
// Команды отсортированных множеств
client.zadd('leaderboard', 100, 'player1');
var score = client.zscore('leaderboard', 'player1');
var top = client.zrange('leaderboard', 0, 9);
// Управление ключами
client.del('key1', 'key2');
client.exists('key1');
client.expire('key1', 3600);
var ttl = client.ttl('key1');
Все команды возвращают объекты { value, error }. Пулы соединений разделяются между VU и автоматически очищаются при завершении теста. Ключи, созданные через set, hset, lpush, rpush, sadd и zadd, получают TTL по умолчанию 12 часов для предотвращения остаточных тестовых данных.
Автоматические метрики: redis_commands (счётчик), redis_cmd_duration (тренд), redis_cmd_failed (частота).
mockarty/sql
SQL-клиент для баз данных (PostgreSQL) с пулом соединений.
var sql = require('mockarty/sql');
var db = sql.open('postgres', 'postgres://user:pass@localhost:5432/testdb?sslmode=disable');
// Запрос (возвращает массив объектов-строк)
var users = db.query('SELECT id, name, email FROM users WHERE active = $1 LIMIT $2', [true, 100]);
check(users, {
'found users': function (u) { return u.length > 0; },
'first user has name': function (u) { return u[0].name !== ''; },
});
// Выполнение (возвращает { rowsAffected: N })
var result = db.exec('UPDATE users SET last_login = NOW() WHERE id = $1', [users[0].id]);
// Параметризованные запросы — передавайте параметры массивом или аргументами
db.query('SELECT * FROM orders WHERE user_id = $1 AND status = $2', userId, 'pending');
Пулы соединений разделяются между VU. Метод close() на уровне VU ничего не делает; пулы очищаются при остановке движка.
mockarty/encoding
Утилиты кодирования/декодирования.
var encoding = require('mockarty/encoding');
// JSON
var obj = encoding.jsonParse('{"name":"Alice"}'); // → { name: "Alice" }
var str = encoding.jsonStringify({ name: 'Alice' }); // → '{"name":"Alice"}'
// Base64
var encoded = encoding.base64Encode('Hello, World!'); // → "SGVsbG8sIFdvcmxkIQ=="
var decoded = encoding.base64Decode('SGVsbG8sIFdvcmxkIQ=='); // → "Hello, World!"
mockarty/faker
Генерация фейковых данных для реалистичных тестовых нагрузок.
var faker = require('mockarty/faker');
var user = {
id: faker.uuid(),
firstName: faker.firstName(),
lastName: faker.lastName(),
email: faker.email(),
username: faker.username(),
password: faker.password(),
phone: faker.phoneNumber(),
ip: faker.ipv4(),
bio: faker.sentence(),
registered: faker.rfc3339(),
creditCard: faker.ccNumber(),
jwt: faker.jwt(),
};
Доступные функции:
| Категория | Функции |
|---|---|
| Персона | firstName, firstNameMale, firstNameFemale, lastName, name, titleMale, titleFemale |
| Интернет | email, username, password, url, domainName, ipv4, ipv6, macAddress |
| UUID | uuid, uuidDigit |
| Адрес | latitude, longitude |
| Дата и время | date, timeString, monthName, yearString, dayOfWeek, dayOfMonth, timestamp, unixTime, rfc3339, century, timezone, timePeriod |
| Текст | word, sentence, paragraph |
| Платежи | ccType, ccNumber, currency, amountWithCurrency |
| Телефон | phoneNumber, tollFreePhoneNumber, e164PhoneNumber |
| Типы | bool, positiveInt, negativeInt, jwt |
Все функции faker потокобезопасны и используют собственное состояние генератора случайных чисел.
mockarty/data
Общие массивы данных для data-driven тестов.
var data = require('mockarty/data');
// SharedArray выполняет фабрику ОДИН РАЗ, затем разделяет результат между всеми VU
var users = data.SharedArray('users', function () {
return [
{ username: 'alice', password: 'pass123' },
{ username: 'bob', password: 'pass456' },
{ username: 'charlie', password: 'pass789' },
];
});
module.exports.default = function () {
// Доступ по индексу (безопасно для VU, только чтение)
var idx = Math.floor(Math.random() * users.length);
var user = users.get(idx);
var http = require('mockarty/http');
http.post('https://api.example.com/login',
JSON.stringify(user),
{ headers: { 'Content-Type': 'application/json' } }
);
};
Фабричная функция выполняется ровно один раз (первым VU, запросившим данные), и последующие VU получают ссылку на те же данные без копирования. Это идеально для загрузки больших наборов данных (CSV-файлы, JSON-массивы) без дублирования памяти между VU.
mockarty/core
Базовые утилитные функции. Они также доступны как глобальные (check, sleep, group, fail), поэтому импорт модуля необязателен.
var core = require('mockarty/core');
// Check — валидация значения по именованным проверкам
core.check(response, {
'status is 200': function (r) { return r.status === 200; },
});
// Sleep — пауза выполнения на N секунд
core.sleep(1.5);
// Group — организация проверок и запросов в именованные группы
core.group('user login flow', function () {
// запросы и проверки внутри группы
});
// Fail — немедленное прерывание текущей итерации
core.fail('Unexpected response');
Глобальные функции
Следующие функции всегда доступны без импорта какого-либо модуля:
| Функция | Описание |
|---|---|
check(value, checks) |
Выполнение именованных проверок. Возвращает true, если все пройдены. |
sleep(seconds) |
Пауза выполнения VU. |
group(name, fn) |
Группировка связанных операций для отчётности. |
fail(reason) |
Прерывание текущей итерации с ошибкой. |
Пользовательские метрики
Создание пользовательских метрик как глобальных объектов:
// Counter — накапливает итог
var myCounter = new Counter('my_custom_counter');
myCounter.add(1);
// Trend — отслеживает распределение (min, max, avg, перцентили)
var myTrend = new Trend('my_custom_trend');
myTrend.add(42.5);
// Rate — отслеживает соотношение успехов/неудач
var myRate = new Rate('my_custom_rate');
myRate.add(true); // успех
myRate.add(false); // неудача
// Gauge — отслеживает текущее значение
var myGauge = new Gauge('my_custom_gauge');
myGauge.add(7);
Пользовательские метрики отображаются в порогах и итоговом отчёте наряду со встроенными метриками.
Пороги и SLA
Пороги определяют критерии прохождения/провала теста. При нарушении любого порога результат теста помечается как проваленный.
export const options = {
vus: 50,
duration: '2m',
thresholds: {
'http_req_duration': [
'avg < 200', // Среднее время ответа менее 200 мс
'p(95) < 500', // 95-й перцентиль менее 500 мс
'p(99) < 1000', // 99-й перцентиль менее 1 сек
'max < 3000', // Ни одного запроса дольше 3 сек
],
'http_req_failed': [
'rate < 0.01', // Менее 1% ошибок
],
'checks': [
'rate > 0.95', // 95% проверок пройдено
],
'iterations': [
'count > 1000', // Минимум 1000 итераций выполнено
],
// Пользовательские метрики тоже работают
'my_custom_trend': [
'avg < 100',
'p(90) < 200',
],
},
};
Синтаксис выражений порогов
<статистика> <оператор> <значение>
Статистики: avg, min, max, med, count, rate, p(N) (где N — перцентиль, напр., p(50), p(95), p(99))
Операторы: <, <=, >, >=, ==, !=
Результаты порогов
После завершения теста каждый порог оценивается и выводится в отчёте:
All thresholds passed:
PASS [http_req_duration] avg < 200: actual=87.34
PASS [http_req_duration] p(95) < 500: actual=245.12
PASS [http_req_failed] rate < 0.01: actual=0.00
Или с нарушениями:
Threshold violations:
PASS [http_req_duration] avg < 200: actual=87.34
FAIL [http_req_duration] p(95) < 500: actual=612.89
PASS [http_req_failed] rate < 0.01: actual=0.00
Критерии прерывания
Критерии прерывания позволяют движку остановить тест досрочно, когда условия указывают на серьёзную проблему, предотвращая потерю времени и ресурсов.
export const options = {
vus: 100,
duration: '10m',
abortCriteria: [
{
name: 'High error rate',
metric: 'http_req_failed',
stat: 'rate',
condition: '>',
value: 0.5,
duration: '30s', // Должно сохраняться 30 сек перед прерыванием
enabled: true,
},
{
name: 'Latency spike',
metric: 'http_req_duration',
stat: 'p95',
condition: '>',
value: 5000, // p95 > 5 секунд
duration: '1m',
enabled: true,
},
],
};
Поле duration требует, чтобы условие сохранялось в течение указанного периода перед срабатыванием. Это предотвращает прерывание при кратковременных всплесках. Если duration не указан или равен "0s", прерывание срабатывает немедленно.
Поддерживаемые метрики для прерывания: http_req_failed (rate), http_req_duration (avg, p90, p95, p99, min, max), http_reqs (count, rate), checks (rate).
При срабатывании прерывания отчёт теста содержит stoppedReason: "auto_stop: High error rate".
Оценка APDEX
Каждый нагрузочный тест автоматически рассчитывает оценку APDEX (Application Performance Index). APDEX — это отраслевой стандарт метрики, переводящий время отклика в оценку удовлетворённости пользователей от 0 до 1.
Как рассчитывается APDEX
APDEX использует порог удовлетворённости T (по умолчанию: 500 мс) для классификации каждого запроса:
| Зона | Условие | Описание |
|---|---|---|
| Удовлетворён | время_ответа <= T | Пользователи удовлетворены производительностью. |
| Терпит | T < время_ответа <= 4T | Пользователи замечают задержки, но терпят их. |
| Разочарован | время_ответа > 4T или ошибка | Пользователи разочарованы. Все ошибки считаются разочарованием. |
Формула:
APDEX = (Удовлетворённые + Терпящие * 0.5) / Всего
Шкала оценок
| Оценка | Рейтинг |
|---|---|
| >= 0.94 | Отлично |
| >= 0.85 | Хорошо |
| >= 0.70 | Удовлетворительно |
| >= 0.50 | Плохо |
| < 0.50 | Неприемлемо |
APDEX в отчётах
APDEX рассчитывается как глобально, так и по маршрутам:
{
"summary": {
"apdex": {
"score": 0.92,
"rating": "Good",
"satisfied": 4500,
"tolerating": 350,
"frustrated": 150,
"total": 5000,
"thresholdT": 500
},
"per_route_stats": [
{
"route": "GET /users/{id}",
"count": 2500,
"apdex": {
"score": 0.98,
"rating": "Excellent"
}
},
{
"route": "POST /orders",
"count": 2500,
"apdex": {
"score": 0.86,
"rating": "Good"
}
}
]
}
}
APDEX по маршрутам помогает определить, какие конкретные эндпоинты снижают общую оценку.
Распределённое выполнение
Для масштабных тестов Mockarty поддерживает распределённое выполнение через Runner Agent’ы. Вместо выполнения теста на узле администрирования координатор направляет задачи производительности на удалённые runner-агенты.
Как это работает
- Узел администрирования получает запрос на тест и создаёт задачу типа
performance. - Координатор (gRPC-сервис на порту 5773) сопоставляет задачу с доступным runner-агентом, имеющим возможность
performance. - Runner-агент принимает задачу, выполняет скрипт с помощью perfengine и передаёт обновления прогресса обратно.
- Узел администрирования собирает итоговый отчёт и сохраняет его в базе данных.
Настройка Runner Agent
Скачайте бинарь mockarty-runner для вашей платформы со страницы releases и запустите:
COORDINATOR_ADDR=mockarty:5773 \
API_TOKEN=mki_your_integration_token \
RUNNER_NAME=perf-runner-1 \
CAPABILITIES=performance \
PERF_ENABLED=true \
MAX_CONCURRENT_TASKS=4 \
./mockarty-runner
| Переменная окружения | По умолчанию | Описание |
|---|---|---|
COORDINATOR_ADDR |
— | gRPC-адрес административной ноды (host:5773) — обязателен для режима grpc |
API_TOKEN |
— | Токен интеграции типа test_runner (создайте через UI администратора > Интеграции) |
RUNNER_NAME |
mockarty-runner |
Понятное имя для этого runner’а |
CAPABILITIES |
api_test,performance |
Возможности через запятую. Должно включать performance, чтобы runner принимал задачи нагрузочного тестирования |
PERF_ENABLED |
true |
Флаг движка нагрузочного тестирования. Установите false, чтобы отключить load testing на этом runner даже если performance включён в CAPABILITIES |
MAX_CONCURRENT_TASKS |
3 |
Максимум одновременных выполнений тестов на этом runner |
SHARED |
true |
Если true, принимает задачи из всех пространств имён |
NAMESPACE |
— | Обязателен при SHARED=false. Принимает задачи только для этого пространства имён |
Важно. Runner, у которого
performanceесть вCAPABILITIES, но который запущен сPERF_ENABLED=false, будет отклонять нагрузочные задачи. Оба флага должны совпадать. ИспользуйтеPERF_ENABLED=falseкак быстрый runtime-переключатель, чтобы вывести runner из работы по нагрузочным задачам без перезапуска с другим списком capabilities.
Полный справочник переменных runner (TLS, режим polling, reverse, метки, drain timeout) см. в Интеграции. Подробнее об архитектуре развёртывания — в разделе Архитектура масштабирования.
Планирование
Нагрузочные тесты можно запускать по расписанию cron для непрерывного мониторинга производительности.
Создание расписания
Расписания связывают сохранённую конфигурацию производительности с cron-выражением:
// POST /api/v1/perf-schedules
{
"name": "Nightly Load Test",
"configId": "config-uuid-here",
"cronExpression": "0 2 * * *",
"namespace": "default",
"enabled": true,
"options": {
"vus": 50,
"duration": "5m"
}
}
Cron-выражение использует стандартный 5-полевой формат: минута час день-месяца месяц день-недели.
Как работает планирование
- Фоновый цикл проверяет расписания каждые 60 секунд.
- Когда время
nextRunAtрасписания наступило, координатор создаёт задачуperformance. - Задача направляется на доступный runner-агент (или выполняется локально, если runner’ы не настроены).
- После выполнения
nextRunAtпересчитывается по cron-выражению. - При некорректном cron-выражении расписание автоматически отключается для предотвращения бесконечных повторных попыток.
Параметры, специфичные для расписания, переопределяют параметры сохранённой конфигурации, позволяя запускать один и тот же скрипт с разными параметрами по разным расписаниям.
Чтение результатов
Сводные метрики
Каждый отчёт теста включает сводку со следующими ключевыми метриками:
| Метрика | Описание |
|---|---|
http_req_duration.avg |
Среднее время ответа (мс) |
http_req_duration.med |
Медиана (p50) времени ответа |
http_req_duration.p90 |
90-й перцентиль времени ответа |
http_req_duration.p95 |
95-й перцентиль времени ответа |
http_req_duration.p99 |
99-й перцентиль времени ответа |
http_req_duration.min |
Самый быстрый ответ |
http_req_duration.max |
Самый медленный ответ |
http_reqs.count |
Общее количество запросов |
http_reqs.rate |
Запросов в секунду (пропускная способность) |
http_req_failed.rate |
Частота ошибок (0.0-1.0) |
data_sent |
Всего байт отправлено |
data_received |
Всего байт получено |
vus_max |
Пиковое количество одновременных VU |
iterations.count |
Всего итераций выполнено |
checks.rate |
Процент пройденных проверок (0-100%) |
Дополнительные показатели
| Метрика | Описание |
|---|---|
stddev_ms |
Стандартное отклонение времени ответа |
cv_pct |
Коэффициент вариации (%) — чем ниже, тем стабильнее |
throughput_stability_cv |
Коэффициент вариации RPS во времени — чем ниже, тем стабильнее пропускная способность |
Разбивка по маршрутам
Отчёт включает статистику по маршрутам для всех протоколов:
- HTTP:
GET /users/{id},POST /orders - gRPC:
gRPC mypackage.UserService/GetUser - SOAP:
SOAP GetWeather - MCP:
MCP tool get_weather - Kafka:
Kafka produce orders,Kafka consume orders - RabbitMQ:
RMQ publish /task_queue,RMQ consume task_queue - WebSocket:
WS connect /ws,WS send /ws,WS recv /ws - SSE:
SSE /events
Каждая запись маршрута включает количество, частоту ошибок, перцентили задержки и собственную оценку APDEX.
Данные временных рядов
Отчёт включает данные временных рядов, сэмплированные каждые 3 секунды для построения графиков:
- Задержка (среднее и p95 во времени)
- Пропускная способность (запросов в секунду во времени)
- Активные VU во времени
- Частота ошибок во времени
Сводки по протоколам
При использовании не-HTTP модулей отчёт включает дополнительные сводки:
{
"grpc_reqs": { "count": 5000, "err_rate": 0.02, "duration": { "avg": 12.3, "p95": 45.6 } },
"kafka_msgs": { "total": 10000, "produced": 5000, "consumed": 5000, "err_rate": 0.0 },
"rmq_msgs": { "total": 8000, "produced": 4000, "consumed": 4000 },
"ws_msgs": { "connections": 100, "sent": 5000, "received": 4800 },
"sse_events": { "connections": 0, "events": 25000 }
}
Продвинутые паттерны
Нарастание / Снижение нагрузки (Стресс-тест)
Моделирование постепенного увеличения трафика для поиска точки отказа:
export const options = {
stages: [
{ duration: '2m', target: 50 }, // Прогрев
{ duration: '3m', target: 200 }, // Нарастание до пика
{ duration: '5m', target: 200 }, // Удержание пика
{ duration: '2m', target: 50 }, // Снижение
{ duration: '1m', target: 0 }, // Охлаждение
],
thresholds: {
'http_req_duration': ['p(95) < 1000'],
'http_req_failed': ['rate < 0.05'],
},
};
Корреляция (Извлечение токенов из ответов)
Связывание запросов путём извлечения значений из одного ответа и использования их в следующем:
var http = require('mockarty/http');
module.exports.default = function () {
// Шаг 1: Авторизация и извлечение токена
var loginRes = http.post('https://api.example.com/auth/login',
JSON.stringify({ username: 'testuser', password: 'testpass' }),
{ headers: { 'Content-Type': 'application/json' } }
);
var token = loginRes.json().token;
// Шаг 2: Использование токена в последующих запросах
var profileRes = http.get('https://api.example.com/profile', {
headers: { 'Authorization': 'Bearer ' + token },
});
check(profileRes, {
'profile loaded': function (r) { return r.status === 200; },
});
// Шаг 3: Создание заказа
var orderRes = http.post('https://api.example.com/orders',
JSON.stringify({ product: 'widget', quantity: 1 }),
{ headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
}}
);
var orderId = orderRes.json().id;
// Шаг 4: Проверка статуса заказа
var statusRes = http.get('https://api.example.com/orders/' + orderId, {
headers: { 'Authorization': 'Bearer ' + token },
});
check(statusRes, {
'order exists': function (r) { return r.status === 200; },
'order is pending': function (r) { return r.json().status === 'pending'; },
});
};
Пользовательские метрики
Отслеживание метрик, специфичных для приложения, наряду со встроенными:
var http = require('mockarty/http');
var loginDuration = new Trend('login_duration');
var orderSuccess = new Rate('order_success_rate');
var totalOrders = new Counter('total_orders');
module.exports.options = {
vus: 20,
duration: '5m',
thresholds: {
'login_duration': ['avg < 300', 'p(95) < 1000'],
'order_success_rate': ['rate > 0.95'],
},
};
module.exports.default = function () {
var start = Date.now();
var res = http.post('https://api.example.com/login',
JSON.stringify({ user: 'test', pass: 'test' }),
{ headers: { 'Content-Type': 'application/json' } }
);
loginDuration.add(Date.now() - start);
var orderRes = http.post('https://api.example.com/orders',
JSON.stringify({ item: 'widget' }),
{ headers: { 'Content-Type': 'application/json' } }
);
orderSuccess.add(orderRes.status === 201);
totalOrders.add(1);
sleep(1);
};
Data-driven тесты
Используйте SharedArray для загрузки тестовых данных, создаваемых один раз и разделяемых между всеми VU:
var http = require('mockarty/http');
var data = require('mockarty/data');
var faker = require('mockarty/faker');
// Создание 1000 тестовых пользователей один раз, разделяемых между всеми VU
var users = data.SharedArray('test-users', function () {
var result = [];
for (var i = 0; i < 1000; i++) {
result.push({
email: faker.email(),
password: faker.password(),
name: faker.name(),
});
}
return result;
});
module.exports.options = {
vus: 50,
duration: '5m',
};
module.exports.default = function () {
// Каждый VU выбирает случайного пользователя
var idx = Math.floor(Math.random() * users.length);
var user = users.get(idx);
http.post('https://api.example.com/register',
JSON.stringify(user),
{ headers: { 'Content-Type': 'application/json' } }
);
sleep(0.5);
};
Мультипротокольный тест
Тестирование HTTP, gRPC и Kafka в одном скрипте:
var http = require('mockarty/http');
var grpc = require('mockarty/grpc');
var kafka = require('mockarty/kafka');
var grpcClient = grpc.connect('localhost:4770', { reflect: true, plaintext: true });
var kafkaProducer = kafka.producer({ brokers: ['localhost:9092'] });
module.exports.options = {
vus: 10,
duration: '2m',
};
module.exports.default = function () {
// HTTP: Создание заказа через REST
var orderRes = http.post('http://localhost:8080/api/orders',
JSON.stringify({ product: 'widget', qty: 1 }),
{ headers: { 'Content-Type': 'application/json' } }
);
check(orderRes, {
'order created': function (r) { return r.status === 201; },
});
// gRPC: Проверка остатков через gRPC
var invRes = grpcClient.invoke('inventory.Service/GetStock', {
product_id: 'widget',
});
check(invRes, {
'gRPC OK': function (r) { return r.status === 'OK'; },
'stock available': function (r) { return r.message.quantity > 0; },
});
// Kafka: Публикация события заказа
kafkaProducer.produce({
topic: 'order-events',
messages: [{ key: 'widget', value: JSON.stringify({ event: 'order_placed' }) }],
});
sleep(1);
};
Реальный пример: Поток оформления заказа в интернет-магазине
Комплексный нагрузочный тест, имитирующий реалистичный путь пользователя в интернет-магазине:
import http from 'k6/http';
import { check, sleep, group } from 'k6';
const BASE_URL = 'https://api.mystore.com';
export const options = {
stages: [
{ duration: '1m', target: 25 }, // Прогрев
{ duration: '3m', target: 100 }, // Нарастание до стабильного состояния
{ duration: '5m', target: 100 }, // Удержание нагрузки
{ duration: '2m', target: 200 }, // Пиковый трафик
{ duration: '2m', target: 200 }, // Удержание пика
{ duration: '1m', target: 0 }, // Охлаждение
],
thresholds: {
'http_req_duration': ['p(95) < 800', 'p(99) < 2000'],
'http_req_failed': ['rate < 0.02'],
'checks': ['rate > 0.98'],
},
abortCriteria: [
{
name: 'Error rate too high',
metric: 'http_req_failed',
stat: 'rate',
condition: '>',
value: 0.3,
duration: '1m',
enabled: true,
},
],
};
export default function () {
const headers = { 'Content-Type': 'application/json' };
// 1. Авторизация
let token;
group('login', function () {
const loginRes = http.post(BASE_URL + '/auth/login',
JSON.stringify({
email: 'loadtest-' + Math.floor(Math.random() * 10000) + '@example.com',
password: 'TestPass123!',
}),
{ headers: headers }
);
check(loginRes, {
'login status 200': (r) => r.status === 200,
'login has token': (r) => r.json().token !== undefined,
});
token = loginRes.json().token;
});
sleep(1);
const authHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
};
// 2. Просмотр товаров
group('browse', function () {
const listRes = http.get(BASE_URL + '/products?page=1&limit=20', {
headers: authHeaders,
});
check(listRes, {
'products loaded': (r) => r.status === 200,
'has products': (r) => r.json().items.length > 0,
});
// Просмотр случайного товара
const products = listRes.json().items;
const randomProduct = products[Math.floor(Math.random() * products.length)];
const detailRes = http.get(BASE_URL + '/products/' + randomProduct.id, {
headers: authHeaders,
});
check(detailRes, {
'product detail loaded': (r) => r.status === 200,
});
});
sleep(2);
// 3. Добавление в корзину
let cartId;
group('add to cart', function () {
const cartRes = http.post(BASE_URL + '/cart/items',
JSON.stringify({
productId: 'prod-001',
quantity: 2,
}),
{ headers: authHeaders }
);
check(cartRes, {
'item added to cart': (r) => r.status === 200 || r.status === 201,
});
cartId = cartRes.json().cartId;
});
sleep(1);
// 4. Оформление заказа
group('checkout', function () {
const checkoutRes = http.post(BASE_URL + '/checkout',
JSON.stringify({
cartId: cartId,
paymentMethod: 'credit_card',
shippingAddress: {
street: '123 Load Test Ave',
city: 'Performance City',
zip: '12345',
},
}),
{ headers: authHeaders }
);
check(checkoutRes, {
'checkout succeeded': (r) => r.status === 200 || r.status === 201,
'has order ID': (r) => r.json().orderId !== undefined,
});
});
sleep(3);
}
Этот скрипт:
- Имитирует реалистичное время обдумывания с помощью
sleep()между действиями - Использует блоки
group()для пошаговой отчётности в результатах - Извлекает токены аутентификации и использует их между запросами
- Наращивает трафик через фазы прогрева, стабильного состояния и пика
- Определяет пороги для p95/p99 задержки и частоты ошибок
- Включает критерий прерывания для досрочной остановки при превышении 30% ошибок
Как интерпретировать результаты

После завершения тестового запуска страница результатов отображает графики и сводные таблицы. Вот как их читать:
Начните с оценки APDEX. Это единственное число (от 0 до 1) показывает, были бы пользователи удовлетворены. Выше 0.94 — отлично; ниже 0.70 — сервис требует внимания. Если APDEX низкий, посмотрите разбивку по маршрутам, чтобы найти, какие эндпоинты его снижают.
Проверьте таблицу порогов. Каждый заданный порог отмечен как PASS или FAIL с фактическим значением. Если хотя бы один порог нарушен, общий результат теста — “провален”. Именно эту метрику стоит использовать для блокировки CI/CD-пайплайна.
Читайте график задержки. График отображает среднее и p95 время ответа на протяжении теста. Обращайте внимание на эти паттерны:
- Ровная линия — здоровый сервис. Время ответа стабильно независимо от нагрузки.
- Постепенный рост — сервис упирается в лимит ресурсов (CPU, соединения с БД, память). Точка, где задержка начинает расти — это потолок вашей мощности.
- Внезапный всплеск — что-то сломалось в этот момент (исчерпание пула соединений, пауза сборщика мусора и т.д.). Сопоставьте временную метку с логами приложения.
Читайте график пропускной способности. Он показывает запросы в секунду во времени. Должен соответствовать вашему профилю нарастания VU. Если пропускная способность выходит на плато, а VU продолжают расти — сервис достиг максимальной мощности.
Проверьте частоту ошибок. Частота ошибок выше 1-2% при нормальной нагрузке обычно указывает на баг. Частота ошибок, растущая с нагрузкой, указывает на проблему мощности (таймауты, отказы соединений).
Посмотрите статистику по маршрутам. Некоторые эндпоинты могут быть в 10 раз медленнее других. Таблица по маршрутам показывает количество, перцентили задержки, частоту ошибок и APDEX для каждого маршрута отдельно, позволяя точно определить, какой API является узким местом.
Типовые паттерны тестирования
Smoke-тест (дымовой тест)
Smoke-тест использует минимальную нагрузку (1-2 VU на 30-60 секунд) для проверки корректности скрипта и доступности целевого сервиса. Запускайте его перед каждым полноценным нагрузочным тестом для раннего обнаружения ошибок скрипта или проблем окружения — без траты времени на долгий запуск.
Нагрузочный тест (Load Test)
Нагрузочный тест имитирует нормальный уровень продакшн-трафика (например, 50-200 VU на 5-15 минут) для измерения базовой производительности. Используйте его для установления нормальной пропускной способности и перцентилей задержки вашего сервиса. Запускайте нагрузочные тесты регулярно (ежедневно или при каждом деплое) для обнаружения регрессий производительности до того, как они затронут пользователей.
Стресс-тест (Stress Test)
Стресс-тест постепенно увеличивает нагрузку сверх нормального уровня для поиска точки отказа вашей системы. Используйте этапы нарастания для увеличения VU от нормального до 2-5x вашего ожидаемого пика и наблюдайте, где начинаются всплески задержки или ошибки. Это показывает потолок мощности и то, как сервис деградирует при перегрузке (плавно или катастрофически).
Spike-тест (тест на всплеск)
Spike-тест имитирует внезапный всплеск трафика — например, прыжок с 10 до 500 VU за несколько секунд, удержание 1-2 минуты, затем спад. Он выявляет, как система справляется с резкими изменениями нагрузки: flash-распродажи, вирусные моменты или DDoS-подобные паттерны. Обратите внимание, восстанавливается ли время ответа после прохождения всплеска.
Soak-тест (тест на выдержку)
Soak-тест подаёт умеренную нагрузку в течение длительного периода (от 30 минут до нескольких часов) для выявления проблем, проявляющихся только со временем: утечки памяти, исчерпание пула соединений, рост файлов логов, блокировки в базе данных или проблемы истечения кеша. Если задержка постепенно растёт во время soak-теста — в сервисе есть утечка ресурсов.
Использование CLI
В Mockarty CLI встроена команда нагрузочного тестирования, которая выполняется локально и не требует запущенного сервера:
# Базовый запуск
mockarty-cli perf run script.js
# С параметрами
mockarty-cli perf run script.js --vus 10 --duration 1m --rps 200
# Из HAR-файла
mockarty-cli perf run --har traffic.har --vus 5 --duration 30s
# С экспортом результатов
mockarty-cli perf run script.js --vus 50 --duration 2m --rps 500 \
--out json:results.json --out html:report.html
| Флаг | По умолчанию | Описание |
|---|---|---|
--vus |
1 |
Количество виртуальных пользователей |
--duration |
30s |
Длительность теста (формат Go duration) |
--rps |
0 |
Целевая частота запросов в секунду (0 — режим по VU) |
--har |
HAR-файл для генерации сценария нагрузки | |
--out |
Формат и файл экспорта. Можно указать несколько раз. Форматы: json:FILE, html:FILE |
Ограничения бесплатного тарифа: 5 VU, 100 RPS, максимум 2 минуты. Для снятия ограничений перейдите на PRO.
Использование SDK
Все SDK предоставляют объект Perf() (или perf) со следующими методами:
| Метод | Описание |
|---|---|
Run(config) |
Запустить новый нагрузочный тест |
Stop(taskID) |
Остановить выполняющийся тест |
Results() |
Список всех результатов тестов |
GetResult(id) |
Получить отдельный результат по ID |
Compare(ids) |
Сравнить несколько запусков |
ListConfigs() |
Список сохранённых конфигураций |
GetConfig(id) |
Получить конфигурацию по ID |
CreateConfig(config) |
Создать новую конфигурацию |
UpdateConfig(id, config) |
Обновить существующую конфигурацию |
DeleteConfig(id) |
Удалить конфигурацию |
DeleteResult(id) |
Удалить результат |
GetResultHistory(configID) |
Получить историю результатов для конфигурации |
GetResultTrend(configID) |
Получить тренд производительности для конфигурации |
ListSchedules() |
Список всех расписаний |
CreateSchedule(schedule) |
Создать периодическое расписание |
UpdateSchedule(id, schedule) |
Обновить расписание |
DeleteSchedule(id) |
Удалить расписание |
RunCollection(req) |
Запустить тест из коллекции |
Пример на Go:
task, err := client.Perf().Run(ctx, &mockarty.PerfConfig{
Name: "Load Test",
Script: scriptContent,
VUs: 50,
Duration: "2m",
})
// Ожидание и получение результатов
result, err := client.Perf().GetResult(ctx, task.ID)
// Сравнение двух запусков
comparison, err := client.Perf().Compare(ctx, []string{result1.ID, result2.ID})
См. также
- Справочник API — REST API эндпоинты для управления конфигурациями производительности, запуска тестов и получения результатов
- Интеграции — настройка Runner Agent’ов для распределённого выполнения тестов
- Справочник Faker — все доступные генераторы фейковых данных для мок-ответов и тестовых данных
- Архитектура масштабирования — распределённое развёртывание с Runner Agent и резолверами
- Рекордер — запись трафика и экспорт в скрипты нагрузочного тестирования
- Фаззинг — автоматизированное тестирование безопасности API
- Контрактное тестирование — валидация моков против спецификаций и проверка обратной совместимости