For .NET projects, the most common manual way is using: coverlet 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: Typical enterprise flow: dotnet test
-> code coverage
-> stryker mutation test
-> CI/CD quality gate
dotnet test --collect:"XPlat Code Coverage"
or dotnet test /p:CollectCoverage=true Then open: coveragereport/index.html 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. Inside your test project folder: dotnet add package coverlet.msbuild This adds the MSBuild integration of Coverlet. dotnet test /p:CollectCoverage=true After running, you’ll see something like: +--------+------+--------+--------+ | Module | Line | Branch | Method | +--------+------+--------+--------+ and a generated file: coverage.json 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 Whenever code changes: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura then:
reportgenerator -reports:coverage.cobertura.xml -targetdir:coveragereport
Built-in collector:
dotnet test --collect:"XPlat Code Coverage"
Coverlet MSBuild: dotnet test /p:CollectCoverage=true Both are valid. But Coverlet gives: Example threshold: dotnet test /p:CollectCoverage=true /p:Threshold=80 This FAILS the build if coverage goes below 80%.