Как устроен coverage отчёт?

В Elixir coverage отчёт — это инструмент для анализа того, какая часть кода была выполнена во время тестов, то есть отчёт о покрытии кода тестами. Это позволяет оценить, насколько полно протестировано приложение и какие участки остаются нетронутыми тестами. В Elixir используется встроенный механизм покрытия кода от Erlang (модуль :cover), который интегрируется через mix test с флагом --cover.

Как включить coverage отчёт

Чтобы получить отчёт о покрытии, нужно запустить тесты с флагом --cover:

mix test --cover

При этом Elixir:

  • компилирует проект с включённым флагом покрытия;

  • запускает тесты;

  • собирает данные о том, какие строки были исполнены;

  • показывает консольный отчёт с процентом покрытия по каждому модулю.

Консольный результат

Пример вывода:

Generating cover results ...
Percentage | Module
\-----------|-----------------------------
100.00% | MyApp.Calculator
80.00% | MyApp.Accounts.User
75.00% | MyApp.Repo
0.00% | MyApp.UnusedModule
\-----------|-----------------------------
Total | 85.71%

Каждая строка показывает:

  • процент строк, покрытых тестами;

  • имя модуля.

Настройка в mix.exs

Покрытие можно настраивать через конфигурацию:

def project do
\[
app: :my_app,
version: "0.1.0",
elixirc_paths: elixirc_paths(Mix.env()),
test_coverage: \[tool: ExCoveralls\],
preferred_cli_env: \[
"coveralls": :test,
"coveralls.detail": :test,
"coveralls.html": :test
\]
\]
end

Для базового покрытия стандартной ExUnit достаточно mix test --cover, но можно подключить ExCoveralls, чтобы получить HTML-отчёты, интеграцию с CI и т.д.

Какие строки считаются покрытыми?

  • Строки с исполняемым кодом (например, вызовы функций, ветвления, выражения) считаются покрытыми, если были выполнены хотя бы один раз во время теста.

  • Неиспользованные ветки (например, else, case, cond) — непокрыты, если туда не заходило выполнение.

  • Определения функций, которые не вызываются в тестах — также считаются непокрытыми.

ExCoveralls: расширение для отчётности

ExCoveralls — это сторонняя библиотека, которая предоставляет:

  • HTML-отчёты;

  • формат JSON для CI;

  • отчёт с детализацией по строкам;

  • интеграцию с GitHub Actions, Travis CI, CircleCI.

Установка:

def deps do
\[
{:excoveralls, "~> 0.16", only: :test}
\]
end

Запуск:

mix coveralls.html

После этого появится файл cover/excoveralls.html с интерактивным HTML-отчётом.

Интерпретация HTML-отчёта

HTML-отчёт ExCoveralls подсвечивает строки:

  • зелёным — покрытые;

  • красным — непокрытые;

  • жёлтым — частично покрытые (например, не все ветви if/case/cond).

Также указывается общее покрытие в процентах и детализация по каждому модулю и строке.

Исключения и фильтрация

Можно исключить некоторые модули из покрытия:

\# mix.exs
test_coverage: \[
tool: ExCoveralls,
ignore_modules: \[~r/SomeHelper$/, MyApp.Seeds\]
\]

Покрытие в многопоточном коде

Покрытие работает и в async: true тестах. :cover — модуль из Erlang, и он поддерживает многопроцессное выполнение.

Важно:

  • Старт тестов с ExUnit.start() должен быть настроен правильно.

  • ExCoveralls автоматически вызывает :cover.start() при запуске.

Очистка отчётов

Чтобы удалить старые HTML-файлы и начать заново:

mix clean
rm -rf cover/
mix coveralls.html

Покрытие — это один из способов контролировать тестовое покрытие и улучшать качество кода. Инструменты вроде ExCoveralls позволяют интегрировать это в ежедневную разработку и CI-процессы.