Computing code coverage for a .NET project

  • Gérald Barré

In an older post, I wrote about how to compute code coverage for a .NET Core project with Coverlet. In this post, I'll show you how to get code coverage without any additional dependency. Indeed, the .NET SDK 8 now includes all you need to compute code coverage. Microsoft also provides a .NET tool to process the coverage files.

Let's start by creating a new xUnit project and removing the dependency on coverlet.collector as we don't need it anymore:

dotnet new xunit
dotnet remove package coverlet.collector

You can then run the tests and compute the code coverage with the following command:

dotnet test --results-directory "test-results" --collect:"Code Coverage"
dotnet test --results-directory "test-results" --collect:"Code Coverage;Format=cobertura"

The --collect:"Code Coverage" argument tells the test runner to collect code coverage data. The coverage files are saved in the test-results directory. The coverage files are saved in a VS-specific format (.coverage) which is not understood by other tools. You can change the output format using "Code Coverage;Format=cobertura" or you can convert them to the Cobertura format using the dotnet tool dotnet-coverage (documentation):

dotnet tool update --global dotnet-coverage

The coverage reports are stored in folders that are named using random GUID. Such folders are hard to find and merge. Hopefully dotnet-coverage support globbing:

dotnet-coverage merge --output test-result.cobertura.xml --output-format cobertura "test-results/**/*.coverage"

Then, you can do whatever you want with the Cobertura file. For example, you can publish it as an artifact in Azure DevOps or generate a nice HTML report with ReportGenerator:

dotnet tool install --global dotnet-reportgenerator-globaltool
reportgenerator -reports:test-result.cobertura.xml -targetdir:coverage-report -reporttypes:"Html_Dark"

If you use GitHub Actions, you can also publish the coverage summary as a Job Summary, so the coverage is easily accessible from the run:


    runs-on: ubuntu-latest
      - uses: actions/checkout@v4
      - run: dotnet test --results-directory "test-results" --collect:"Code Coverage"
      - run: dotnet tool update --global dotnet-coverage
      - run: dotnet-coverage merge --output test-result.cobertura.xml --output-format cobertura "test-results/**/*.coverage"
      - run: dotnet tool install --global dotnet-reportgenerator-globaltool
      - run: reportgenerator -reports:test-result.cobertura.xml -targetdir:coverage-report -reporttypes:"MarkdownSummaryGithub"
      - run: cat coverage-report/ >> $GITHUB_STEP_SUMMARY

Code coverage displayed as a job summary in GitHub Actions

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub