Как устроен 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-процессы.