9to5 coverage · Docs

Elixir code coverage with ExCoveralls

Generate an LCOV report from ExUnit and upload it to GitHub PR checks with ExCoveralls.

Configure ExCoveralls in your Mix project

Add ExCoveralls as a test dependency and configure Mix to use it. Merge these entries into your existing project and dependency lists; do not replace the rest of mix.exs.

# In project/0:
test_coverage: [tool: ExCoveralls]

# In deps/0:
{:excoveralls, "~> 0.18", only: :test}

Generate the report

MIX_ENV=test mix deps.get
MIX_ENV=test mix coveralls.lcov
# Default output: cover/lcov.info

The output directory can be overridden in coveralls.json. Keep that setting and the upload path consistent. If your Phoenix tests need PostgreSQL or other services, configure them in CI before running coverage.

Upload after the tests

- uses: erlef/setup-beam@v1
  with:
    otp-version: '28.3'
    elixir-version: '1.19.4'
- run: mix deps.get
  env:
    MIX_ENV: test
- run: mix coveralls.lcov
  env:
    MIX_ENV: test
- uses: 9to5/9to5-coverage-action@v1
  with:
    token: ${{ secrets.COVERAGE_UPLOAD_TOKEN }}
    path: cover/lcov.info

These steps belong after checkout in a job triggered for default-branch pushes and PRs. Match OTP and Elixir versions to your project. ExCoveralls emits a report locally; the name does not require sending it to Coveralls.

Check exclusions and generated templates

Review skip_files and ignored modules before trusting a percentage. Erlang coverage data may attribute generated template execution to the containing module rather than individual HEEx files. Combine coverage with rendered-page tests and behavior assertions.

ExCoveralls reference · Our own coverage workflow