Coverlet Documentation

repository·master·Indexed 25 days ago

https://github.com/coverlet-coverage/coverlet

A cross-platform code coverage framework for .NET supporting line, branch, and method coverage. It provides multiple integration options including coverlet.collector for VSTest, coverlet.msbuild for MSBuild, coverlet.console as a global tool, and coverlet.MTP for the Microsoft Testing Platform. Works with .NET Framework on Windows and .NET Core on all supported platforms.

Tokens
23.3K
Snippets
67
Records
115
Agent score
85%

What's inside Coverlet

  1. Understand Coverlet versioning and components

    master

    Coverlet follows Semantic Versioning (SemVer) 2.0.0.

    • MAJOR version: Incremented for incompatible API changes.
    • MINOR version: Incremented for backwards-compatible functionality additions.
    • PATCH version: Incremented for backwards-compatible bug fixes.

    The project is distributed via NuGet as four distinct packages:

    • coverlet.msbuild.nupkg
    • coverlet.console.nupkg
    • coverlet.collector.nupkg
    • coverlet.MTP.nupkg
  2. Understand Coverlet Package Responsibilities

    master

    Coverlet is composed of several packages, each serving a specific integration role. All packages depend on coverlet.core for the actual instrumentation and reporting engine.

    • coverlet.core: The engine responsible for assembly instrumentation, hit tracking, filtering, and multi-format report generation. It requires assemblies with symbols/PDBs.
    • coverlet.collector: Used for VSTest integration. It hooks into the VSTest collector lifecycle to instrument assemblies and emit coverage attachments.
    • coverlet.msbuild: Used for MSBuild/dotnet test integration. It uses MSBuild tasks to manage instrumentation, report generation, and threshold enforcement.
    • coverlet.console: A standalone global tool that orchestrates instrumentation and report output by wrapping an external target process.
    • coverlet.MTP: Used for Microsoft Testing Platform (MTP) integration. It extends the MTP runner to instrument assemblies and generate reports.
  3. Understand the Architecture of Coverlet VSTest Integration

    master

    The coverlet.collector integration uses a controller-style architecture where VSTest acts as the orchestrator. Coverlet hooks into the collector lifecycle callbacks to perform instrumentation and collection.

    Workflow:

    1. vstest.console or dotnet test triggers the out-of-proc coverlet.collector.
    2. coverlet.collector coordinates with the testhost and an in-proc instance of itself.
    3. Both components utilize coverlet.core for IL instrumentation and hit tracking.
    4. coverlet.core generates coverage reports and coverlet.collector publishes coverage as VSTest attachments in the TestResults/<guid> directory.
  4. Debug Collectors integration issues

    master

    To troubleshoot issues with collectors, run your tests with the --collect:"XPlat Code Coverage" flag and enable diagnostic logging using --diag:log.txt. This will generate log files in the same directory (e.g., log.datacollector...txt, log.host...txt, and log.txt). Search these files for the [coverlet] filter to find relevant information.

    dotnet test --collect:"XPlat Code Coverage" --settings runsettings --diag:log.txt
  5. Configure Coverlet MSBuild Integration for Deterministic Builds

    master

    To use Coverlet with deterministic builds via MSBuild integration, you must first generate local NuGet packages from the repository. Then, update your test project file (e.g., XUnitTestProject1.csproj) to reference the locally built version of coverlet.msbuild instead of a public NuGet version.

    Ensure the PackageReference for coverlet.msbuild includes the following assets to work correctly with the MSBuild integration:

    • PrivateAssets: all
    • IncludeAssets: runtime; build; native; contentfiles; analyzers; buildtransitive
    <PackageReference Include="coverlet.msbuild" Version="8.0.1-preview.8.gcb9b802a5f">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  6. Run tests with Deterministic Build settings

    master

    When running tests with Coverlet MSBuild integration for deterministic builds, use the CollectCoverage and DeterministicSourcePaths MSBuild properties.

    Warning: Do not use the --no-build flag, as this prevents the generation of the necessary deterministic build artifacts.

    dotnet test /p:CollectCoverage=true /p:DeterministicSourcePaths=true
  7. Achieve 100% branch coverage for short-circuiting operators

    master

    When using logical operators like && or ||, the compiler generates multiple branches to support short-circuiting. To reach 100% coverage, you must provide test cases that exercise every possible evaluation path.

    For if (a && b)

    This pattern typically reports 4 branches. To cover them, you need at least three distinct test cases:

    1. a=true, b=true (Executes the then block)
    2. a=true, b=false (Short-circuits on b)
    3. a=false (Short-circuits on a; b is not evaluated)

    For if (a || b)

    This pattern also typically reports 4 branches. To cover them, you need:

    1. a=false, b=false (Both evaluated, result false)
    2. a=false, b=true (Short-circuits on b)
    3. a=true (Short-circuits on a; b is not evaluated)

    For Compound Conditions (e.g., if (a && b && c))

    Each additional logical operator increases the branch count. For three conditions, you need cases that fail at each step (e.g., a is false, then b is false, then c is false) plus a case where all are true.

    [Fact]
    public void Test_AllBranches()
    {
        Example(true, true);   // a=true, b=true → executes block
        Example(true, false);  // a=true, b=false → skips block
        Example(false, true);  // a=false → skips block (b not evaluated)
        Example(false, false); // a=false → skips block (b not evaluated)
    }
  8. Configure Coverlet.MTP via MSBuild Property

    master

    You can define Coverlet options in your .csproj file using the TestingPlatformCommandLineArguments property. This allows you to use MSBuild variables like $(AssemblyName) or $(MSBuildProjectName).

    Example for a single project:

    <PropertyGroup>
      <TestingPlatformCommandLineArguments>--coverlet --coverlet-file-prefix $(AssemblyName) --coverlet-output-format opencover</TestingPlatformCommandLineArguments>
    </PropertyGroup>

    Example for solution-wide configuration (via Directory.Build.props):

    <Project>
      <PropertyGroup Condition="'$(IsTestProject)' == 'true'">
        <TestingPlatformCommandLineArguments>--coverlet --coverlet-file-prefix $(MSBuildProjectName)</TestingPlatformCommandLineArguments>
      </PropertyGroup>
    </Project>
    <PropertyGroup>
      <!-- Pass coverlet options via MSBuild - allows using MSBuild variables -->
      <TestingPlatformCommandLineArguments>--coverlet --coverlet-file-prefix $(AssemblyName) --coverlet-output-format opencover</TestingPlatformCommandLineArguments>
    </PropertyGroup>
  9. Use a local build of Coverlet (no collectors)

    master

    To test local changes in the Coverlet source code without using collectors, you can point your test project to your local MSBuild tasks build.

    1. Build the Coverlet repository using dotnet build.
    2. In your target test project, run dotnet test while specifying the path to your local MSBuild tasks using the /p:CoverletToolsPath property.
    dotnet test /p:CollectCoverage=true /p:Exclude="[xunit.*]*" /p:CoverletToolsPath=D:\git\coverlet\src\coverlet.msbuild.tasks\bin\Debug\netstandard2.0\