Синхронизация обнаружения тестов
Об URL в примерах: во всех примерах используется адрес
127.0.0.1:5770по умолчанию. Если ваш экземпляр работает на удалённом сервере, замените его на фактический адрес. Подробнее — Полезные функции и советы.
Синхронизация обнаружения тестов регистрирует весь инвентарь ваших тестов
в каталоге TCM прямо из CI — включая тесты, которые в текущей сборке не
запускались. Вы загружаете небольшой JSON-манифест со списком всех тестов,
которые собрал ваш фреймворк, а Mockarty сверяет его с тест-кейсами
пространства имён: новые тесты создаются, существующие сохраняют свои
человекоориентированные метаданные, а тесты, исчезнувшие из кода, могут быть
помечены как осиротевшие (orphaned).
Это дополняет внешние прогоны: внешний прогон сообщает
Mockarty о тесте только в момент его выполнения. Синхронизация обнаружения
поддерживает каталог живым зеркалом кодовой базы, поэтому тест, который вы
пропустили или поместили в карантин в этой сборке, всё равно виден в TCM.
Что она делает
| Итог | Значение |
|---|---|
| created | Для теста из манифеста ещё не было соответствующего кейса — создан новый кейс. |
| updated | Для теста из манифеста кейс уже существовал — обновлены отметка об обнаружении и (для авто-обнаруженных) имя; ваши ручные правки сохранены. |
| orphaned | Только при pruneMissing: true: кейс, ранее обнаруженный под этим source, отсутствует в текущем манифесте, поэтому помечен как осиротевший. Осиротевшие кейсы никогда не удаляются — они остаются для просмотра и экспорта. |
| total | Число уникальных тестов в манифесте. |
Каждый обнаруженный тест сопоставляется по детерминированной идентичности. Если
вы задали явный testCaseId, он становится авторитетным ключом (он переживает
переименование метода или параметров); иначе используется обязательный
fullName. Это тот же ключ, по которому сопоставляется внешний прогон, поэтому
тест, обнаруженный здесь и позже выполненный, попадает в один и тот же кейс.
Формат манифеста
{
"source": "pytest:auth-suite",
"framework": "pytest",
"pruneMissing": true,
"cases": [
{
"testCaseId": "AUTH-1042",
"fullName": "tests.auth.test_login.test_valid_credentials",
"name": "Вход с корректными учётными данными",
"suite": "tests.auth.test_login",
"description": "Пользователь может войти с верным email и паролем.",
"sourceRef": "tests/auth/test_login.py:42",
"labels": ["auth", "smoke"]
},
{
"fullName": "tests.auth.test_login.test_locked_account",
"name": "Заблокированная учётная запись отклоняется",
"sourceRef": "tests/auth/test_login.py:58"
}
]
}
| Поле | Обязательно | Примечания |
|---|---|---|
source |
да | Ключ области для этого манифеста (например, pytest:auth-suite). Удаление лишних кейсов ограничено одним source, поэтому манифест одного набора никогда не осиротит кейсы другого. |
framework |
нет | Информационное (например, pytest, go, junit). |
pruneMissing |
нет | При true кейсы, обнаруженные под этим source, но отсутствующие в cases, помечаются осиротевшими. При false (по умолчанию) синхронизация только добавляет. |
cases[].fullName |
да | Детерминированная идентичность теста. По ней тест сопоставляется между синхронизациями и с результатами прогонов. |
cases[].testCaseId |
нет | Явная закреплённая автором идентичность (например, @allure.id). При наличии — авторитетный ключ сопоставления. |
cases[].name |
нет | Отображаемое имя. По умолчанию равно fullName. Имя переносится на авто-обнаруженные кейсы при каждой синхронизации; ручные кейсы не затрагиваются. |
cases[].description |
нет | Свободный текст. Устанавливается только при создании кейса, чтобы ваши ручные правки переживали повторные синхронизации. |
cases[].sourceRef |
нет | Где тест находится в коде (file:line или URL репозитория), для «перейти к исходнику». |
cases[].labels |
нет | Становятся тегами кейса при создании. |
cases[].suite |
нет | Необязательная подсказка группировки; зарезервировано для будущего размещения по папкам. |
Синхронизация через API
POST /api/v1/namespaces/{namespace}/tcm/discovery
curl -X POST http://127.0.0.1:5770/api/v1/namespaces/default/tcm/discovery \
-H "Authorization: Bearer $MOCKARTY_API_TOKEN" \
-H "Content-Type: application/json" \
-d @manifest.json
Ответ:
{
"source": "pytest:auth-suite",
"created": 2,
"updated": 18,
"orphaned": 1,
"total": 20
}
Аутентификация и права. Передавайте токен API как
Authorization: Bearer <token>. Эндпойнт требует право test_case:write
(манифест — это запись в рабочее пространство) и функцию TCM.
Синхронизация через CLI
CLI оборачивает эндпойнт командой mockarty-cli tcm discover. Манифест читается
из файла (--manifest <path>) или из stdin (--manifest -).
# Из файла, с областью и удалением лишних кейсов этого source:
mockarty-cli tcm discover --manifest cases.json --source pytest:auth-suite --prune
# Из stdin, в конвейере CI:
pytest --collect-only -q | my-converter | \
mockarty-cli tcm discover --manifest - --source pytest:auth-suite --framework pytest --prune
| Флаг | Назначение |
|---|---|
--manifest |
Путь к JSON-манифесту или - для stdin. Обязательно. |
--source |
Переопределяет верхнеуровневый source манифеста (ключ области для удаления лишних). |
--framework |
Переопределяет верхнеуровневый framework манифеста. |
--prune |
Помечает осиротевшими кейсы, отсутствующие в манифесте (под тем же source). |
Значения флагов имеют приоритет над верхнеуровневыми полями манифеста, поэтому
универсальный конвертер может выдавать манифест без source, а CI затем задаёт
область для каждого набора.
Семантика осиротения (pruneMissing)
Удаление лишних кейсов выполняется по каждому source и не разрушительно:
- Без
pruneMissing(или--prune) синхронизация только добавляет и
обновляет — ничего не осиротеет. - С ним Mockarty сравнивает кейсы, ранее обнаруженные под этим
source, с
текущим манифестом. Исчезнувшие помечаются осиротевшими — это мягкое
состояние, а не удаление. Они остаются видимыми и экспортируемыми, чтобы QA
решил, был ли тест удалён намеренно. - Поскольку удаление лишних ограничено одним
source, запуск манифеста
auth-suiteникогда не затрагивает кейсы, обнаруженные манифестом
checkout-suite.
Повторная синхронизация неизменного манифеста идемпотентна: ничего нового не
создаётся и ничего лишнего не осиротеет.
Ограничение частоты (HTTP 429)
Манифест может содержать тысячи кейсов, каждый — это upsert. Чтобы защитить базу
данных, когда большой парк CI синхронизируется одновременно, сервер ограничивает
число одновременно выполняемых синхронизаций. При достижении предела эндпойнт
возвращает HTTP 429 с заголовком Retry-After: 1:
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Сделайте паузу и повторите. CLI и SDK повторяют 429 с экспоненциальной задержкой
автоматически. Предел параллелизма по умолчанию равен учетверённому числу
процессоров сервера и настраивается администратором переменной окружения
MOCKARTY_DISCOVERY_CONCURRENCY (диапазон 2–1024).
Уведомления
Когда синхронизация действительно меняет каталог — созданы новые кейсы и/или
кейсы осиротели — Mockarty отправляет событие discovery synced в настроенные
вебхуки и каналы уведомлений пространства имён, а также шлёт живое обновление в
любое открытое дерево кейсов, чтобы новые/осиротевшие кейсы появились без ручного
обновления. Холостая повторная синхронизация (всё updated, ничего нового и
осиротевшего) остаётся «тихой», чтобы прогоны CI не засыпали подписчиков.
См. также
- Управление тест-кейсами — каталог, внешние прогоны и метаданные.
- Интеграция с TestIT — включая массовый импорт экспорта Test IT.
- Allure-аннотации в скриптах — идентичность
fullName/testCaseId. - Справочник CLI-команд — полная поверхность
mockarty-cli.