Что здесь обычно болит
GitLab умеет показывать отчёт тестов во вкладке пайплайна, и это удобно ровно до конца сборки. Дальше начинается то, чего вкладка не умеет: сравнить с прошлой неделей, сложить с ручными проверками, понять, кто и когда чинил падение, показать заказчику приёмку. И самое частое: шаг с тестами упал — пайплайн остановился — отчёт не собрался вовсе, поэтому обсуждать нечего.
Шаг выгрузки
report:
stage: test
when: always # без этого отчёт не уедет именно тогда, когда нужен
script:
- curl -fsSL https://qadesk.ru/cli/qadesk-cli-linux-amd64 -o qadesk-cli && chmod +x qadesk-cli
- ./qadesk-cli upload --run "$CI_PROJECT_NAME regress" --env stage ./reports
QADESK_TOKEN кладётся в Settings → CI/CD → Variables как masked и protected: это токен приёма на проект (qdit_…), выпускается в кабинете, показывается один раз, отзывается одной кнопкой. Утилита принимает его только из окружения — флагом нельзя, чтобы он не оказался в логе задания.
Тот же приём работает одним curl без утилиты — см. JUnit XML.
Что утилита возьмёт сама
CI_PIPELINE_ID— ключ идемпотентности: перезапуск задания не создаёт второй прогон;CI_PROJECT_NAME,CI_JOB_NAME,CI_PIPELINE_IID— имя прогона, если не задать--run;- формат отчёта:
*-result.json— Allure, иначе JUnit по*.xml.
GitFlic совместим с GitLab по именам переменных, поэтому для него ничего менять не нужно — тот же шаг работает как есть.
Параллельные задания и матрица
e2e:
parallel: 4
script:
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL --reporter=junit
- ./qadesk-cli upload --attempt $CI_NODE_INDEX --run "e2e" ./reports
Приём идемпотентен по паре «прогон CI + попытка». Четыре шарда с одинаковым CI_PIPELINE_ID и разным содержимым — это конфликт, и он честно отдаст 409, а не перезапишет чужие результаты молча. Разведите шарды через --attempt (как выше) или собирайте отчёты в один каталог и отправляйте одним шагом после needs.
Self-managed и закрытый контур
Если GitLab стоит внутри периметра, меняется только адрес назначения. Утилита принимает --url (или переменную QADESK_URL) — так отчёты уезжают в Коробку, а не в облако. Бинарник статический, зависимостей у него нет, и его удобно один раз положить в свой образ раннера, чтобы не тянуть каждый раз из сети:
image: registry.internal/ci/base:latest # qadesk-cli уже внутри
script:
- qadesk-cli upload --url https://qadesk.internal --run "regress" ./reports
Гейт релиза остаётся вашим
Код выхода утилиты отвечает за доставку отчёта, а не за исход тестов: 0 — принят (в том числе «уже был принят раньше», о чём она скажет вслух), 1 — не дошёл, 2 — ошибка данных, 3 — только с --strict, если часть тестов не легла в прогон. Красный пайплайн из-за упавших тестов делает ваш шаг с тестами, а не выгрузка.
Флаг --strict полезен как отдельная проверка «разметка кейсов не разъехалась»: он свалит задание, если появились тесты без ключа.
Задачи и код
Дефект, заведённый из упавшего результата, живёт в деске: восемь статусов, проверка переходов на сервере, история. Двусторонней связки с issues GitLab пока нет — адаптер в дорожной карте. Сегодня связь с разработкой делается через SourceCraft (задача из карточки дефекта, обратно приходят статус и закрывший пул-реквест с хешем сборки) или через Битрикс24.
Так честнее, чем нарисовать логотип GitLab в разделе интеграций: приём отчётов из GitLab CI работает сегодня, адаптер задач — нет.
С чего начать
- Выпустите токен приёма и положите его в CI/CD Variables (masked, protected).
- Добавьте шаг
reportсwhen: always. - Прогоните пайплайн и откройте ссылку на прогон — утилита печатает её последней строкой.
- Проставьте ключи кейсов, чтобы автотесты и ручные проверки сложились в одно покрытие.
Попробуйте на своём проекте
Заведите проект, загрузите первый отчёт или заведите первый дефект — бесплатный тариф без карты. Нужно демо на ваших сценариях — напишите на hello@qadesk.ru.
Создать проектРядом по теме
Playwright
Playwright пишет отчёт, QA Деск делает из него прогон: ключ кейса связывает автотест с ручной проверкой, повтор задания не плодит дубли, а упавший сценарий превращается в дефект.
Playwright — сценарии в браузере, результат в покрытииJUnit XML
Своего формата у QA Деск нет: подойдёт JUnit XML, который ваш раннер уже пишет. Один запрос из пайплайна — и отчёт становится прогоном с историей, покрытием и дефектами.
JUnit XML — формат, который умеет писать всёSourceCraft CI
Отчёт уезжает из кубика CI одной командой, а дефект связывается с задачей SourceCraft: обратно в карточку приходят статус задачи и пул-реквест, закрывший её, с хешем влитой сборки.
SourceCraft — от дефекта до влитого пул-реквеста