10 июля 2026 г.
Продукт

Как мы тестируем наши плагины для Medusa

Каждый плагин @gorgo ежедневно проходит юнит-, интеграционные и контрактные тесты против реальных API провайдеров и проверяется на последней версии Medusa, чтобы ваши магазины работали стабильно. Рассказываем, как устроен этот процесс.

Как мы тестируем наши плагины для Medusa

Устанавливая плагин приёма платежей или доставки, вы доверяете ему оформление заказа, и ошибка здесь стоит реальных денег. Поэтому тестирование каждого пакета в монорепозитории medusa-plugins автоматизировано полностью, от юнит-тестов до ежедневных проверок против боевых API провайдеров. В этой статье разберём, какие тесты мы запускаем, насколько они покрывают каждый плагин и как проверяется совместимость с последней версией Medusa.

Сейчас в репозитории 81 тестовый файл и 543 тест-кейса на шесть плагинов.

Типы тестов и зачем они нужны

Юнит-тесты

Юнит-тесты проверяют логику провайдера в изоляции, без сети и базы данных: сопоставление статусов, генерацию подписи, формирование чеков, разбор ошибок. Исходящие HTTP-запросы перехватывает MSW, поэтому легко проверить реакцию плагина на любой ответ провайдера, включая сценарии, которые сложно воспроизвести вручную: отклонённый платёж, некорректный вебхук, повторно отправленное событие.

Интеграционные тесты

Интеграционные тесты находятся в отдельных пакетах и поднимают полноценное приложение Medusa с установленным плагином и базой PostgreSQL через . Тестовая база создаётся и удаляется на каждом прогоне. HTTP-тесты проходят admin- и store-маршруты целиком, module-тесты обращаются к сервисам напрямую. Часть приёмов — структуру тестов и работу с тестовой базой — мы подсмотрели в самом репозитории Medusa, где эти инструменты используются для тестирования ядра.

Контрактные тесты

Юнит- и интеграционные тесты имитируют внешний сервис, поэтому не заметят изменений на его стороне. Контрактные тесты решают обратную задачу: обращаются к API провайдера (ЮKassa, Т-Касса, Robokassa, ApiShip) и проверяют, что форматы запросов и ответов, которые использует плагин, всё ещё совпадают с фактическими.

В CI эти тесты выполняются ежедневно с действующими ключами API. Любое несовместимое изменение на стороне провайдера, будь то переименованное поле, новый статус или более строгая валидация, приводит к ошибкам в тестах. Вот, например, проверка, которая заметит новый статус жизненного цикла платежа:

yookassa-sandbox.contract.spec.ts
1const KNOWN_STATUSES = [
2 "pending",
3 "waiting_for_capture",
4 "succeeded",
5 "canceled",
6] as const
7
8// ...
9
10let client: YooCheckout
11
12beforeAll(() => {
13 client = new YooCheckout({ shopId: SHOP_ID!, secretKey: SECRET_KEY! })
14})
15
16it("createPayment → getPayment → cancelPayment honours the documented lifecycle contract", async () => {
17 const idempotencyKey = `contract-no-receipt-${Date.now()}`
18 const payment = await sdkCall(() =>
19 client.createPayment(
20 {
21 amount: { value: "10.00", currency: "RUB" },
22 confirmation: { type: "redirect", return_url: "https://example.com/return" },
23 description: "medusa-plugin contract test (no receipt)",
24 metadata: { session_id: idempotencyKey, receip_tmp: "{}" },
25 },
26 idempotencyKey
27 )
28 )
29
30 expect(payment.id).toBeDefined()
31 expect(payment.status).toBeDefined()
32 expect(KNOWN_STATUSES).toContain(payment.status as any)
33 expect(payment.amount.value).toBe("10.00")
34 expect(payment.amount.currency).toBe("RUB")
35 expect(payment.confirmation).toBeDefined()
36 expect((payment.confirmation as any).confirmation_url).toMatch(/^https:\/\//)
37 // ...
38})

Тестовое покрытие плагинов

Покрытие разное. Глубже всего протестированы платёжные плагины с помощью юнит-, интеграционных и контрактных тестов, ведь цена ошибки при оплате самая высокая. У самая большая кодовая база и самый большой набор тестов. Плагин находится в разработке, пока в нём только базовый smoke-тест.

Ниже актуальные цифры по каждому плагину. Проценты оценочные и отражают глубину тестирования, а не точное line-покрытие.

ПлагинЮнитИнтеграционныеКонтрактныеПокрытиеБадж
88114~90%Протестировано с Medusa
76115~90%Протестировано с Medusa
6074~85%Протестировано с Medusa
1498019~80%Протестировано с Medusa
0210~60%Протестировано с Medusa
010~5%Протестировано с Medusa

Что стоит за баджем «Протестировано с Medusa»

Бадж в README каждого плагина обновляется автоматически. Каждое утро воркфлоу выполняет следующие шаги:

  1. Считывает последнюю версию из npm.
  2. Сравнивает её с версией, на которой плагин проверялся в последний раз.
  3. Обновляет зависимости в каждой отстающей установке плагина до новой версии Medusa.
  4. Прогоняет полный набор тестов всех плагинов.
  5. Пересоздаёт бадж только для плагинов, чьи тесты прошли, и открывает пул-реквест со всеми обновлениями.

Плагины при этом изолированы друг от друга: если один ломается на новом релизе Medusa, он исключается из обновления, а остальные тестируются дальше.

Так это выглядит на практике. 25 июня утренний прогон обнаружил свежую Medusa v2.17.1, обновил и проверил все шесть плагинов примерно за десять минут. Пять прошли, а не собрался: в новой версии из типа исчезло поле . Плагин остался на предыдущей проверенной версии, а поломка видна в пул-реквесте #358.

Пул-реквест #358: пять плагинов протестированы на Medusa v2.17.1, 1c исключён из обновления

Сам бадж хранится в репозитории как JSON-файл, который отрисовывается с помощью shields.io. Значение в нём означает, что тесты плагина действительно прошли на этой версии:

.badges/medusa-payment-yookassa.json
1{
2 "schemaVersion": 1,
3 "label": "Tested with Medusa",
4 "message": "v2.17.1",
5 "color": "green"
6}

Расписание и триггеры

За автоматизацию отвечают три воркфлоу GitHub Actions:

ВоркфлоуТриггерыЧто делает
Ежедневно в 04:00 UTC, каждый PR/push в или вручнуюЮнит-, интеграционные и контрактные тесты
Ежедневно в 06:00 UTC или вручнуюПроверка на последней Medusa, обновление баджей, открытие PR
Push в Версионирование и публикация изменённых пакетов через Changesets

В пул-реквестах запускает тесты только для изменившихся плагинов. Ночной прогон и ручной запуск тестируют всё.

Как устроен репозиторий

1medusa-plugins/
2├── examples/ # примеры проектов Medusa с интегрированными плагинами, версия Medusa всегда последняя
3├── integration-tests/ # установки Medusa c интеграционными и контрактными тестами на каждый плагин
4├── packages/ # npm-пакеты плагинов, юнит-тесты рядом с кодом
5├── .badges/ # JSON «Протестировано с Medusa» на каждый плагин
6├── scripts/ # обновление до новой Medusa и пересборка баджей
7├── .github/workflows/ # test, update-medusa-version, publish
8└── ...

Поддержка и сообщество Medusa в Telegram

Все тесты открыты, их можно посмотреть в репозитории gorgojs/medusa-plugins, а описания плагинов в документации. Вопросы и сообщения об ошибках ждём в чате поддержки Gorgo и Telegram-сообществе Medusa. Issues и Pull Requests тоже всегда приветствуются.