Go - относительно молодой и динамично развивающийся язык. Инструменты и библиотеки для языка довольно быстро меняются. Поэтому при поиске каких-то типовых решений часто натыкаешься на устаревшие подходы и в процессе работы узнаешь, что некоторые вещи можно решить проще. Например, так получилось с измерением покрытия кода тестами. На GitHub довольно много библиотек и скриптов для оценки покрытия мультипакетных проектов на Go, но оказывается, все можно решить с помощью встроенных инструментов. По крайней мере, это касается наиболее свежей версии v1.12 на текущий момент.
В заметке приведена инструкция по настройке измерения покрытия тестами для приватного проекта на GitLab.
Измерение покрытия тестами
Предположим, что у нас есть мультипакетный проект на Go со структурой, описанной в golang-standards/project-layout. В проекте есть тесты разных категорий. Unit-тесты расположены в пакетах internal
, pkg
, функциональные и интеграционные тесты в директории test
. Стоит задача подсчитать общее покрытие всего кода всеми возможными видами тестов. Сделать это можно двумя инструкциями.
Запуск всех тестов и запись профиля покрытия в файл coverage.out
.
|
|
Вывод отчета о покрытии в консоли.
|
|
Вывод последней команды будет содержать подробные проценты покрытия по всем функциям в пакетах и в конце строчку с общим процентом покрытия всех модулей.
|
|
Настройка GitLab CI
Разберем настройку GitLab CI на примере файла .gitlab-ci.yml
. Задача - измерять покрытие тестами и выводить в виде значка в файле README.md
(на главной странице проекта) и генерировать отчет с подробным профилем покрытия в виде статичных HTML-страниц на GitLab Pages.
|
|
Конфигурация состоит из двух задач test
и pages
, разделенных на два этапа test
и deploy
соответственно. Первая задача отвечает за тестирование кода с составлением профиля покрытия, который передается на следующий этап с помощью артефактов. Вторая задача отвечает за генерирование HTML-отчета и его доставку на статические страницы GitLab Pages.
Рассмотрим подробно каждую инструкцию задачи test
.
stage: test
- привязка задачиtest
к стадииtest
image: golang/alpine
- использование Docker-образа golang/alpinebefore_script:
go version
- вывод версии Go (для диагностики потенциальных проблем)go get
- установка зависимостей (подразумевается, что в проекте находится файл модулейgo.mod
)
script
- рассмотренные выше инструкции для тестирования кода и вывода отчета в консольartifacts
- сохранение профиля покрытияcoverage.out
для следующей стадии (если нет необходимости генерировать HTML-отчет, то этот раздел можно не указывать)
Основные инструкции для доставки отчета на GitLab Pages задачи pages
.
stage: deploy
- задача привязывается к стадии доставки кода (ее следует запускать после доставки кода на релизный сервер, например)dependencies
- обязательно нужно указать задачу, на которой были сгенерированы артефакты, иначе они не загрузятся для текущей задачиscript
go tool cover -html=coverage.out -o coverage.html
- гененирование стандартного HTML-отчета о покрытии модулейrm -rf public
- удаление директории (если такая есть в репозитории проекта), которая необходима для статичных страниц GitLab Pagesmkdir -p public
- создание пустой директорииcp coverage.html ./public/index.html
- копирование отчета в директориюpublic
, которая будет обслуживаться web-сервером GitLab Pagesartifacts
- необходимы для загрузки на GitLab Pagesonly
- доставку отчета следует делать только для основной веткиmaster
“Вишенкой на торте” служит значок coverage
с процентом покрытия тестами в файле README.md
. В GitLab CI существует встроенный инструмент генерирования значков. Чтобы настроить автоматическое генерирование значка необходимо зайти на страницу настроек проекта Settings -> CI/CI -> General pipelines
(путь актуален для версии GitLab v11.8) и указать регулярное выражение ^total:.*\d+.\d+%
, которое будет парсить вывод команды go tool cover
и сохранять процент покрытия. Затем необходимо скопировать текст для вставки значка в markdown-синтаксисе и вставить его в файл README.md
.