Code Coverage .NET

Code Coverage .NET

For .NET projects, the most common manual way is using:

  • coverlet
  • or built-in dotnet test --collect:"XPlat Code Coverage"

Simplest first:

dotnet test --collect:"XPlat Code Coverage"

After running, you’ll see something like:

Attachments:
.../coverage.cobertura.xml

That XML file contains the coverage result.

Then install the report generator globally:

dotnet tool install -g dotnet-reportgenerator-globaltool

Generate an HTML report:

reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coveragereport

Then open:

coveragereport/index.html

You’ll see:

  • Line coverage
  • Branch coverage
  • Covered/not covered lines
  • Per class/service/controller coverage

Typical enterprise flow:

dotnet test
-> code coverage
-> stryker mutation test
-> CI/CD quality gate

Question

  • What is the official steps after setting-up above?
dotnet test --collect:"XPlat Code Coverage"

or

dotnet test /p:CollectCoverage=true

Then open:

coveragereport/index.html

COVERLET

Coverlet is the more common approach in real .NET projects now because it integrates nicely with CI/CD and gives flexible reporting.

Here’s the normal flow.

1. Install Coverlet in your TEST project

Inside your test project folder:

dotnet add package coverlet.msbuild

This adds the MSBuild integration of Coverlet.

2. Run coverage manually

dotnet test /p:CollectCoverage=true

After running, you’ll see something like:

+--------+------+--------+--------+
| Module | Line | Branch | Method |
+--------+------+--------+--------+

and a generated file:

coverage.json

3. Generate HTML report (better UI)

Usually we use Cobertura format:

dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura

Then generate HTML:

reportgenerator -reports:coverage.cobertura.xml -targetdir:coveragereport

Open:

coveragereport/index.html

Future workflow now

Whenever code changes:

dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura

then:

reportgenerator -reports:coverage.cobertura.xml -targetdir:coveragereport

Difference from built-in collector

Built-in collector:

dotnet test --collect:"XPlat Code Coverage"

Coverlet MSBuild:

dotnet test /p:CollectCoverage=true

Both are valid.

But Coverlet gives:

  • easier CI/CD integration
  • thresholds
  • filtering
  • merging reports
  • multiple formats
  • more enterprise flexibility

Example threshold:

dotnet test /p:CollectCoverage=true /p:Threshold=80

This FAILS the build if coverage goes below 80%.