Наборы и тест-кейсы

Каталог как код

Suite хранится в JSON рядом с исходным кодом. Изменение теста проходит review, имеет историю Git и доставляется в Hub идемпотентным импортом.

Минимальная структура:

{
  "environment": {
    "name": "stage1",
    "base_url": "https://stage1.videograce.ru",
    "secret_ref": ""
  },
  "suite": {
    "slug": "videograce-chat-smoke",
    "name": "VideoGrace chat smoke",
    "description": "Критические сценарии чатов"
  },
  "cases": []
}

Ручной кейс

{
  "id": "CHAT-001",
  "title": "Отправка текстового сообщения",
  "description": "Проверяет доставку между двумя online-клиентами",
  "priority": "critical",
  "execution": "manual",
  "manual_steps": [
    "Открыть личный чат на двух клиентах",
    "Отправить уникальное сообщение с первого клиента",
    "Проверить доставку и статус на обоих клиентах"
  ],
  "expected": [
    "Сообщение появляется без reload",
    "Порядок контактов не меняется от простого открытия",
    "Статус доставки обновляется"
  ]
}

Combined-кейс

{
  "id": "MEDIA-004",
  "title": "Повторное включение микрофона",
  "priority": "critical",
  "execution": "combined",
  "manual_steps": [
    "Войти в конференцию с микрофоном",
    "Выключить и снова включить микрофон",
    "Проверить звук со второго клиента"
  ],
  "expected": [
    "UI и серверное состояние совпадают",
    "После включения идет исходящий RTP",
    "Звук слышен второму участнику"
  ],
  "agent": {
    "required_capabilities": [
      "conference.participant",
      "media.diagnostics"
    ],
    "actions": [
      "join_conference",
      "disable_microphone",
      "enable_microphone"
    ],
    "assert": [
      "member_state_synced",
      "audio_rtp_restored_within_sec=10"
    ]
  }
}

actions и assert не исполняются самим Hub. Их семантика определяется конкретным runner-ом.

Declarative HTTP-кейс

{
  "id": "API-001",
  "title": "Health API",
  "priority": "critical",
  "execution": "agent",
  "expected": ["HTTP 200", "status=ok"],
  "agent": {
    "driver": "http",
    "required_capabilities": ["http"],
    "timeout_sec": 10,
    "stop_on_failure": true,
    "requests": [
      {
        "name": "health",
        "method": "GET",
        "path": "/api/v1/health",
        "expect": {
          "status": 200,
          "max_elapsed_ms": 3000,
          "json": [
            {"path": "status", "equals": "ok"}
          ]
        }
      }
    ]
  }
}

HTTP runner поддерживает:

  • методы GET, HEAD, POST, PUT, PATCH, DELETE;
  • JSON и text body;
  • status, max_elapsed_ms, body_contains;
  • JSON path assertions equals и exists;
  • timeout запроса от 1 до 120 секунд.

Путь обязан начинаться с / и не может сменить origin окружения. Redirect на другой origin считается ошибкой.

Импорт через UI

  1. Откройте Наборы тестов.
  2. Вставьте JSON в блок импорта.
  3. Нажмите Импортировать или обновить.
  4. Проверьте состав suite перед запуском.

Импорт требует роль qa_lead или admin.

Импорт через API

curl -fsS https://qa.videograce.ru/api/v1/catalog/import \
  -H "Authorization: Bearer $QA_TOKEN" \
  -H 'Content-Type: application/json' \
  --data-binary @my-suite.json

Повторный импорт с тем же suite.slug:

  • обновляет suite;
  • обновляет кейсы по id;
  • обновляет порядок;
  • не переписывает snapshot уже созданных прогонов.

Правила хорошего тест-кейса

  1. Один кейс проверяет один наблюдаемый результат.
  2. Шаг начинается с действия, а expected — с проверяемого эффекта.
  3. В шаге нет скрытого «подготовить как обычно».
  4. Внешние ID стабильны и не переиспользуются для другой проверки.
  5. Critical-кейс воспроизводим на чистом окружении.
  6. Agent assertions измеримы и имеют timeout.
  7. Cleanup описан или встроен в runner.

Версионирование

В текущей схеме нет отдельного номера версии suite. Источником истории является Git, а конкретный прогон фиксирует build и snapshot кейсов. Если изменение полностью меняет назначение набора, создайте новый slug, а не переопределяйте старый.