Отчёты проверки и JUnit
Курс «Лаборатория GitLab CI/CD»
Проверка course-card уже различает отсутствие артефакта и несовпадение содержимого. Полная программа архива создаёт JSON для подробных сведений и JUnit XML для представления результатов. Теперь разберём их устройство и подключим сохранение обоих файлов в GitLab, включая обычную ошибку проверки. Это собственная проверка статического артефакта, а не запуск Postman, Newman или внешнего API.
Плейлист включает отдельные темы отчётов API-проверок, но их недоступные демонстрации не используются как изученный источник. Текущий урок дополняет курс по официальной документации reports и сохраняет общую лабораторию. Формат отчёта не меняет смысл результата: failed check должен оставаться failed job.
Проверка и представление
verify.mjs выполняет несколько условий: метаданные существуют, схема известна, хэш HTML совпадает, размер файла совпадает, страница содержит заголовок и три карточки. Каждое условие превращается в отдельную запись со статусом и сообщением. Такой разбор помогает увидеть, где нарушился договор, не объединяя всё в одну неопределённую фразу «проверка не прошла».
JSON сохраняется в reports/verify.json. Он может содержать commit, pipeline и массив результатов. Это сведения конкретного job, поэтому отчёт не включаем в кэш и не переносим в dist/. Страница сайта и диагностический результат имеют разный жизненный цикл и разных потребителей.
JUnit — распространённый XML-формат для структурированных результатов. GitLab умеет читать его и показывать записи в интерфейсе. Даже если наша программа является простым валидатором, можно выразить отдельные условия как cases. Имя должно описывать реальную проверку, например index.html sha256, а не случайно одинаковое test у всех записей.
Вид записи
Следующий XML — сокращённый пример формата, который создаёт программа. Он не является результатом фактического запуска. В полном файле количество cases и failures определяется проверенными условиями.
<testsuite name="course-card artifact" tests="2" failures="1">
<testcase classname="artifact" name="release metadata exists" />
<testcase classname="artifact" name="index.html sha256">
<failure message="checksum mismatch">HTML differs from release.json</failure>
</testcase>
</testsuite>
XML-специальные символы в сообщениях нужно экранировать. Путь или текст с & не должен разрушать структуру отчёта. Полная программа архива использует небольшую функцию экранирования и формирует известный набор элементов. Не записывайте JSON в файл с расширением .xml с ожиданием, что GitLab распознает его автоматически.
Два checks с одинаковыми именами могут затруднить сопоставление результатов. В нашем наборе имена устойчивы и связаны с предметом проверки. При добавлении нескольких файлов включайте относительный путь в name либо другой устойчивый идентификатор. Отчёт должен объяснять, какая часть выпуска проверялась.
Сохранение при ошибке
Добавьте к verify-site блок артефактов. Его needs на build-site и команда программы остаются из предыдущего урока. Указанные outputs создаёт сама программа; декларация YAML не выполняет проверки за неё.
artifacts:
when: always
paths:
- reports/
reports:
junit: reports/verify.xml
expire_in: 7 days
when: always позволяет сохранить диагностическую папку также при failed job, если файлы были созданы и Runner дошёл до этапа загрузки. Оно не обещает отчёт при внезапном прекращении окружения или до начала программы. Поэтому валидатор старается обработать обычную предметную ошибку, записать отчёт и затем вернуть код 1.
GitLab использует reports:junit для представления структурированных результатов. Это не способ изменить код завершения job: пустой failures в XML не исправит упавшую команду, а наличие failure само по себе не заменяет корректное завершение программы. Механизм описан в документации JUnit reports.
Обязательная ошибка и полезные сведения
Если хэш не совпал, программа сохраняет ожидаемое и фактическое безопасные значения в JSON, отмечает failure в XML и завершает работу с ненулевым кодом. Следующая обязательная стадия не должна получить разрешение на подготовку такого выпуска. Отчёт лишь делает причину видимой, сохраняя смысл конвейера.
Не добавляйте allow_failure: true к verify ради доступности отчёта. Для сохранения файла уже есть artifacts when. Allow failure означает другое: процесс допускает ошибку этого job. Если проверка целостности становится необязательной, staging может получить неподтверждённый каталог. Это изменение договора, а не косметика интерфейса.
В случае отсутствующего release.json нельзя сразу аварийно завершиться до создания отчёта, если задача состоит в понятной диагностике. Полная программа перехватывает такое условие, записывает failure и затем устанавливает код. При ошибке записи самого reports/ журнал остаётся последним источником причины; отчёт не может гарантировать своё существование при любой поломке среды.
| Состояние | Job | Отчёт | Следующий обязательный шаг |
|---|---|---|---|
| Все условия соблюдены | Success | Успешные cases | Допустим |
| Хэш изменился | Failed | Failure для файла | Не допустим |
| Артефакт не получен | Failed | Failure входа, если запись возможна | Не допустим |
| Runner остановлен до программы | Нет полного результата | Может отсутствовать | Не допустим |
Результаты checks должны иметь устойчивый смысл между запусками. Если сегодня case index.html sha256 проверяет хэш, а завтра только существование файла, одинаковое имя создаст ложную историю сравнения. При существенном изменении проверки обновите описание и при необходимости имя. Кроме того, число cases не является оценкой качества само по себе: пять точных условий для данного артефакта полезнее пятидесяти повторений одной проверки. Добавляйте новое условие, когда оно подтверждает отдельное обязательство выпуска, и объясняйте, какую ошибку обнаруживает. Так структурированный отчёт остаётся инструментом решения, а не декоративным счётчиком.
Неверный JSON может быть синтаксически допустимым: например, release.json содержит null или files: [null]. Такой документ читается парсером, но не отвечает нашей схеме. Валидатор сначала проверяет, что верхний уровень и запись файла являются объектами, затем обращается к их полям. Это позволяет выразить обычное нарушение как failed case и сохранить отчёты. Если сразу читать path у null, возникнет исключение до предметной диагностики. При расширении схемы сохраняйте этот порядок: структура входа, допустимые значения и лишь затем вычисления над файлами.
Что отчёт не оценивает
Проверка хэша подтверждает совпадение bytes с метаданными, а поиск трёх карточек — ограниченное условие структуры. Это не аудит содержания курса, визуальной доступности или корректности всех ссылок. Если HTML содержит три карточки с плохими объяснениями, наш простой validator не обнаружит редакционную проблему. Названия checks должны сохранять эту границу.
Так же JUnit-представление не доказывает, что выполнялась полноценная тестовая система. В лаборатории есть конкретные программные условия для статического результата. При подготовке серии они не запускались; XML в статье и ожидаемые outcomes используются только как спецификация. Нельзя обозначать их как пройденные проверки.
На выходе ожидаем job, который сохраняет предметную причину ошибки и даёт GitLab структурированные результаты. Build-артефакт остаётся отдельно, отчёт относится к verify. Следующим шагом разберём runner и контейнерную среду, чтобы понимать, где именно выполняются эти команды и какие права им предоставлены.