Документация Миграция с k6

Миграция с k6 на Mockarty perfengine

Это руководство показывает, как запускать существующие k6-скрипты под нагрузочным движком Mockarty. Короткая версия: для HTTP-нагрузки вставьте .js как есть и нажмите «Запустить». Модули стандартной библиотеки k6 переписаны нативно — большинство полностью, часть частично. Что потребует правок — смотрите в разделе «Что поддерживается».

Кратко

Ваш текущий k6-скрипт:

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter } from 'k6/metrics';

const errors = new Counter('errors');

export const options = {
  vus: 50,
  duration: '30s',
  thresholds: {
    'http_req_duration': ['p(95)<500'],
  },
};

export default function () {
  const res = http.get('https://api.example.com/users');
  if (!check(res, { 'status was 200': r => r.status === 200 })) {
    errors.add(1);
  }
  sleep(1);
}

Работает без изменений. Mockarty парсит ESM-импорты, переписывает их в нативные require('mockarty/...')-вызовы на этапе компиляции и исполняет тело внутри своего JavaScript-движка. Бинарь k6 не нужен.

HTTP, checks, groups, пороги, кастомные метрики и модель executor’ов/сценариев покрыты хорошо. gRPC, WebSocket, данные из файлов и сторонние библиотеки — нет. Прочитайте таблицу ниже, прежде чем рассчитывать, что скрипт переедет как есть.

Что поддерживается

Модуль k6 Поддержка Mockarty Заметки
k6 (check, sleep, group, fail, randomSeed) Полная
k6/http Частичная get/post/put/del/patch/head/options/request/batch, redirects, tags, auth. Нет: http.cookieJar() и параметр cookies, http.file() и multipart-загрузка файлов, а также res.url / res.html() / res.cookies / res.request.
k6/ws Частичная connect возвращает сокет с send/sendBinary/close. Callback-форма ws.connect(url, params, socket => …) не исполняется, событий socket.on(...) и socket.ping() нет. Событийный k6-скрипт про WebSocket отработает до конца, ничего не сделав — перепишите его на возвращаемый сокет.
k6/grpc Частичная grpc.connect(address, params) возвращает клиент с invoke/close, res.status — строка ("OK"). new grpc.Client(), client.load([], 'x.proto'), grpc.Stream и числовые константы grpc.StatusOK из k6 отсутствуют — gRPC-скрипт надо переписывать, а не переносить.
k6/data Полная SharedArray с одноразовой фабрикой
k6/encoding Полная b64encode/b64decode во всех вариантах (std, rawstd, url, rawurl)
k6/crypto Полная createHash, createHMAC, прямые хеши (md5/sha1/sha256/sha384/sha512/sha512_224/sha512_256/ripemd160), randomBytes, hex, base64
k6/html Полная jQuery-подобный API Selection: find/filter/each/attr/text/html/parent/children/closest/siblings/next/prev/eq/first/last/size/is/not/has/end/add/map/val/data
k6/metrics Полная Counter, Gauge, Rate, Trend — теги работают в .add()
k6/execution Полная instance, vu, scenario, test — live-счётчики, test.abort()
k6/timers Полная setTimeout, setInterval, clearTimeout, clearInterval
k6/redis, k6/experimental/redis Частичная Команды есть, но форма другая: клиент создаётся через redis.open(...), методы синхронные, тогда как в k6 — new redis.Client() и промисы. Цепочку await надо переписать в линейные вызовы.

Что не поддерживается

  • k6/browser / k6/experimental/browser — браузерная автоматизация не входит в нагрузочное ядро. Используйте собственный движок UI-тестирования Mockarty.
  • open() — глобальная функция чтения файла на этапе init. Поэтому не работает и типовой data-driven паттерн new SharedArray('users', () => JSON.parse(open('./users.json'))). Передавайте данные через переменные окружения (__ENV) или генерируйте их функцией.
  • Импорты из https://jslib.k6.io/... и из ваших относительных модулей (./helpers.js). Резолвятся только модули k6/* из таблицы выше; всё остальное остаётся ES-импортом, который компилятор отвергает, — падает весь скрипт. Это касается k6-utils, httpx, k6chaijs и хелпера textSummary, который обычно используют вместе с handleSummary.
  • k6/experimental/{fs,csv,streams,tracing,webcrypto} и k6/secrets.
  • Executor externally-controlled — сценарий с ним пропускается.

Отличия от оригинального k6

Mockarty perfengine — это надмножество: всё, что умеет k6, плюс наши расширения. Несколько практических отличий:

  1. Магические глобалы __VU и __ITER работают, но k6/execution — современный и более мощный аналог. Используйте exec.vu.idInTest и exec.scenario.iterationInTest.
  2. Timers — это event-loop очередь, не raw goroutines. Callback’и setTimeout/setInterval срабатывают в безопасный момент VU-потока: между итерациями или каждые 50 мс внутри sleep(). Это совпадает с поведением k6/браузера. Если запланируете таймер на 5 секунд и сразу выйдете из default-функции — он сработает до начала следующей итерации.
  3. Теги custom-метрик работают через .add(value, { tagName: 'value' }). Агрегация создаёт отдельный bucket на каждый набор тегов плюс untagged-total для обратной совместимости.
  4. Опции (export const options = { ... }): из скрипта читаются ключи vus, duration, iterations, stages, rps, maxVUs, thresholds и scenarios. Все остальные ключи игнорируются, включая summaryTrendStats, insecureSkipTLSVerify, discardResponseBodies, batch, userAgent, maxRedirects, noConnectionReuse, tags и ext. Задавайте нужное в конфигурации запуска.
  5. Executor’ы: поддержаны constant-vus, ramping-vus, per-vu-iterations, shared-iterations, constant-arrival-rate и ramping-arrival-rate. Многосценарный скрипт исполняет сценарии параллельно при запуске через mockarty-cli perf run; при запуске из UI или через раннер профиль нагрузки переносится только из односценарного скрипта — для многосценарного задайте профиль в форме запуска.
  6. Пороги (thresholds): avg, min, max, med, count, rate, value (для gauge) и p(N), включая дробные перцентили вида p(99.9). Порог на метрику, которую движок не собирает, помечается как не вычислен, а не засчитывается как пройденный.
  7. handleSummary(data) вызывается в mockarty-cli perf run, но data — это отчёт Mockarty, а не структура summary из k6. Функцию, написанную под data.metrics['http_req_duration'].values['p(95)'], придётся адаптировать.

Native Mockarty-расширения сверху

Раз k6-скрипт работает, можно подмешивать нативные Mockarty-модули:

  • require('mockarty/kafka') — Kafka producer/consumer
  • require('mockarty/rabbitmq') — RabbitMQ
  • require('mockarty/sql') — SQL через пул соединений
  • require('mockarty/mcp') — драйвер MCP-сервера
  • require('mockarty/faker') — встроенные Faker-функции
  • require('mockarty/allure') — Allure-аннотации

Этого в k6 нет — это наши расширения для протоколов, которые обычно подключают через xk6-плагины.

Как запустить k6-скрипт

  1. API Tester → Performance → Scripts → New в веб-UI Mockarty.
  2. Вставьте .js. Формат определяется автоматически — k6 (ESM) и Mockarty (CommonJS) принимаются оба.
  3. Run. Метрики в реальном времени: RPS, p95-latency, error rate, активные VU.
  4. По завершении: per-route статистика, thresholds pass/fail, custom-метрики. Экспорт в JSON / JUnit XML / Allure.

CI/CD через CLI:

mockarty-cli perf run ./my-script.js --vus 50 --duration 30s

Как работает совместимость

Mockarty запускает поддерживаемые импорты k6/* в собственном нагрузочном движке. Устанавливать бинарник k6 на раннер Mockarty не нужно. Начните с HTTP-скрипта, а перед переносом скриптов с другими модулями проверьте таблицу совместимости выше. Модули с пометкой Частичная и перечисленные как неподдерживаемые потребуют изменений в скрипте.

Сообщить о проблеме

Если k6-скрипт не запускается или выдаёт результат, отличающийся от вывода оригинального k6, — сообщите. Приложите:

  • Версию k6, с которой сравнивали.
  • Минимальный воспроизводящий скрипт.
  • Ошибку Mockarty perfengine (если есть).

Расхождение мы считаем багом, если оно в модуле, помеченном выше как «Полная». Расхождения в модулях с пометкой «Частичная» и всё из раздела «Что не поддерживается» уже известны — они перечислены там, а не заводятся отдельными багами.