coverlet.MTP 8.0.0

Prefix Reserved
dotnet add package coverlet.MTP --version 8.0.0
                    
NuGet\Install-Package coverlet.MTP -Version 8.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="coverlet.MTP" Version="8.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="coverlet.MTP" Version="8.0.0" />
                    
Directory.Packages.props
<PackageReference Include="coverlet.MTP">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add coverlet.MTP --version 8.0.0
                    
#r "nuget: coverlet.MTP, 8.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package coverlet.MTP@8.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=coverlet.MTP&version=8.0.0
                    
Install as a Cake Addin
#tool nuget:?package=coverlet.MTP&version=8.0.0
                    
Install as a Cake Tool

Coverlet Microsoft Testing Platform Integration

Microsoft.Testing.Platform and Microsoft Test Framework is a lightweight alternative for VSTest.

More information is available here:

coverlet.MTP implements coverlet.collector functionality for Microsoft.Testing.Platform.

Supported Runtime Versions

Since version 8.0.0:

  • .NET Core >= 8.0

Quick Start

Installation

Add the coverlet.MTP package to your test project:

dotnet add package coverlet.MTP

ToDo: Usage details

A sample project file looks like:

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
      <OutputType>Exe</OutputType>
      
      <UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
      <TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport> 
   </PropertyGroup>
      <ItemGroup>
      
      <PackageReference Include="xunit.v3.mtp-v2" Version="3.2.1" />
      <PackageReference Include="Microsoft.Testing.Platform" Version="2.0.2" />
      <PackageReference Include="coverlet.MTP" Version="8.0.0" />
   </ItemGroup>
</Project>

Basic Usage

To collect code coverage, run your test executable with the --coverlet flag:

dotnet exec <test-assembly.dll> --coverlet

Or using dotnet test with MTP enabled projects:

dotnet test --coverlet

After the test run, a coverage.json file containing the results will be generated in the current directory.

Command Line Options

The coverlet.MTP extension provides the following command line options. To see all available options, run:

dotnet exec <test-assembly.dll> --help

Coverage Options

Option Description
--coverlet Enable code coverage data collection.
--coverlet-output-format <format> Output format(s) for coverage report. Supported formats: json, lcov, opencover, cobertura, teamcity. Can be specified multiple times.
--coverlet-include <filter> Include assemblies matching filters (e.g., [Assembly]Type). Can be specified multiple times.
--coverlet-include-directory <path> Include additional directories for sources. Can be specified multiple times.
--coverlet-exclude <filter> Exclude assemblies matching filters (e.g., [Assembly]Type). Can be specified multiple times.
--coverlet-exclude-by-file <pattern> Exclude source files matching glob patterns. Can be specified multiple times.
--coverlet-exclude-by-attribute <attribute> Exclude methods/classes decorated with attributes. Can be specified multiple times.
--coverlet-include-test-assembly Include test assembly in coverage.
--coverlet-single-hit Limit the number of hits to one for each location.
--coverlet-skip-auto-props Skip auto-implemented properties.
--coverlet-does-not-return-attribute <attribute> Attributes that mark methods as not returning. Can be specified multiple times.
--coverlet-exclude-assemblies-without-sources <value> Exclude assemblies without source code. Values: MissingAll, MissingAny, None.

Examples

Generate coverage in JSON format (default):

dotnet exec TestProject.dll --coverlet

Generate coverage in Cobertura format:

dotnet exec TestProject.dll --coverlet --coverlet-output-format cobertura

Generate coverage in multiple formats:

dotnet run TestProject.dll --coverlet --coverlet-output-format json --coverlet-output-format cobertura --coverlet-output-format lcov

Include only specific assemblies:

dotnet exec TestProject.dll --coverlet --coverlet-include "[MyApp.]"

Exclude test assemblies and specific namespaces:

dotnet exec TestProject.dll --coverlet --coverlet-exclude "[.Tests]" --coverlet-exclude "[]MyApp.Generated."

Exclude by attribute:

dotnet exec TestProject.dll --coverlet --coverlet-exclude-by-attribute "Obsolete" --coverlet-exclude-by-attribute "GeneratedCode"

Coverage Output

Coverlet can generate coverage results in multiple formats:

  • json (default) - Coverlet's native JSON format
  • lcov - LCOV format
  • opencover - OpenCover XML format
  • cobertura - Cobertura XML format
  • teamcity - TeamCity service messages

Filter Expressions

Filter expressions allow fine-grained control over what gets included or excluded from coverage.

Syntax: [Assembly-Filter]Type-Filter

Wildcards:

  • * matches zero or more characters
  • ? makes the prefixed character optional

Examples:

  • [*]* - All types in all assemblies
  • [coverlet.*]Coverlet.Core.Coverage - Specific class in matching assemblies
  • [*]Coverlet.Core.Instrumentation.* - All types in a namespace
  • [coverlet.*.tests?]* - Assemblies ending with .test or .tests

Both --coverlet-include and --coverlet-exclude can be used together, but --coverlet-exclude takes precedence.

Excluding From Coverage

Using Attributes

Apply the ExcludeFromCodeCoverage attribute from System.Diagnostics.CodeAnalysis to exclude methods or classes:

[ExcludeFromCodeCoverage] public class NotCovered { // This class will be excluded from coverage }

Additional attributes can be specified using --coverlet-exclude-by-attribute.

Using Source File Patterns

Exclude source files using glob patterns with --coverlet-exclude-by-file:

dotnet exec TestProject.dll --coverlet --coverlet-exclude-by-file "**/Generated/*.cs"

How It Works

The coverlet.MTP extension integrates with the Microsoft Testing Platform using the extensibility model:

  1. Test Host Controller Extension: Implements ITestHostProcessLifetimeHandler to instrument assemblies before tests run and collect coverage after tests complete.

  2. Before Tests Run:

    • Locates the test assembly and referenced assemblies with PDBs
    • Instruments assemblies by inserting code to record sequence point hits
  3. After Tests Run:

    • Restores original non-instrumented assemblies
    • Reads recorded hit information
    • Generates coverage report in the specified format(s)

Comparison with coverlet.collector (VSTest)

Feature coverlet.MTP coverlet.collector
Test Platform Microsoft Testing Platform VSTest
Configuration Command line options runsettings file
coverlet.mtp.appsettings.json
Default Format JSON Cobertura

Known Limitations

  • Threshold validation is not yet supported (planned for future releases)
  • Report merging is not yet supported (use external tools like dotnet-coverage or reportgenerator)

Merging coverage files from multiple test runs:

Use dotnet-coverage tool:

dotnet-coverage merge coverage/**/coverage.cobertura.xml -f cobertura -o coverage/merged.xml

Or use reportgenerator:

reportgenerator -reports:"**/*.cobertura.xml" -targetdir:"coverage/report" -reporttypes:"HtmlInline_AzurePipelines_Dark;Cobertura"

Architecture

Coverlet.MTP uses a two-process architecture:

flowchart LR
    subgraph Controller["CONTROLLER PROCESS"]
        direction TB
        THC["builder.TestHostControllers"]
        PLH["AddProcessLifetimeHandler"]
        EVP["AddEnvironmentVariableProvider"]
        THC --> PLH
        THC --> EVP
    end

    subgraph TestHost["TEST HOST PROCESS"]
        direction TB
        TH["builder.TestHost"]
        TSLH["AddTestSessionLifetimeHandle"]
        DC["AddDataConsumer"]
        TALC["AddTestApplicationLifecycleCallbacks"]
        TH --> TSLH
        TH --> DC
        TH --> TALC
    end

    Controller -->|"Environment Variables<br/>Process Lifecycle Events"| TestHost

    style Controller fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style TestHost fill:#e6ffe6,stroke:#009900,stroke-width:2px

And here's a sequence diagram showing the coverlet.MTP flow:

sequenceDiagram
    participant C as Controller Process<br/>(CoverletExtensionCollector)
    participant E as Environment Variables
    participant T as Test Host Process<br/>(CoverletInProcessHandler)

    Note over C: BeforeTestHostProcessStartAsync
    C->>C: Instrument assemblies
    C->>E: Set COVERLET_MTP_COVERAGE_ENABLED=true
    C->>E: Set COVERLET_MTP_COVERAGE_IDENTIFIER
    C->>E: Set COVERLET_MTP_HITS_FILE_PATH

    Note over C: OnTestHostProcessStartedAsync
    C->>T: Start test host process

    Note over T: Constructor
    T->>E: Read environment variables
    T->>T: Initialize handler

    Note over T: OnTestSessionStartingAsync
    T->>T: Tests execute...

    Note over T: OnTestSessionFinishingAsync
    T->>T: FlushCoverageData()
    T->>T: Call ModuleTrackerTemplate.UnloadModule

    Note over C: OnTestHostProcessExitedAsync
    C->>C: Read hit files
    C->>C: Generate coverage reports

Environment Variables

Variable Purpose
COVERLET_MTP_COVERAGE_ENABLED Indicates coverage is active
COVERLET_MTP_COVERAGE_IDENTIFIER Unique ID for result correlation
COVERLET_MTP_HITS_FILE_PATH Directory for hit data files
COVERLET_MTP_INPROC_DEBUG Set to "1" to debug in-process handler
COVERLET_MTP_INPROC_EXCEPTIONLOG_ENABLED Set to "1" for detailed error logging

Troubleshooting

Enable Diagnostic Output

Use the MTP diagnostic options to get detailed logs:

dotnet exec TestProject.dll --coverlet --diagnostic --diagnostic-verbosity trace --diagnostic-output-directory ./logs

Debug Coverlet Extension

Set the environment variable to attach a debugger:

set COVERLET_MTP_DEBUG=1 dotnet exec TestProject.dll --coverlet

Debugging and Troubleshooting (not tested - just defined)

Enable Debugger Launch

To launch a debugger when coverlet.MTP initializes:

Windows:

set COVERLET_MTP_DEBUG=1

Linux/macOS:

export COVERLET_MTP_DEBUG=1

Wait for Debugger Attach

To make coverlet.MTP wait for a debugger to attach (Windows):

set COVERLET_MTP_DEBUG_WAIT=1

The extension will display:

[Coverlet.MTP] CoverletExtension: Waiting for debugger to attach... [Coverlet.MTP] Process Id: 12345, Name: dotnet

Use Visual Studio's "Debug > Attach to Process" (Ctrl+Alt+P) to attach.

Enable Tracker Logging

To collect detailed logs from the injected coverage tracker (Windows):

set COVERLET_ENABLETRACKERLOG=1

Log files will be created near the instrumented module location:

  • moduleName.dll_tracker.txt - Main tracker log
  • TrackersHitsLog/ folder - Detailed hit information

Enable Instrumentation Debugging

For detailed instrumentation diagnostics (Windows):

set COVERLET_MTP_INSTRUMENTATION_DEBUG=1

Enable Exception Logging

To capture detailed exception information (Windows):

set COVERLET_MTP_EXCEPTIONLOG_ENABLED=1

Using MTP Built-in Diagnostics

Microsoft Testing Platform provides built-in diagnostic logging (Windows):

dotnet test --diagnostic --diagnostic-verbosity Trace

This creates detailed logs in the TestResults directory.

Combined Debugging Example

Enable all debugging features (Windows)

set COVERLET_MTP_DEBUG_WAIT=1 set COVERLET_ENABLETRACKERLOG=1 set COVERLET_MTP_EXCEPTIONLOG_ENABLED=1

Run tests with MTP diagnostics

dotnet test --coverlet --diagnostic --diagnostic-verbosity Trace

Requirements

  • .NET 8.0 SDK or newer
  • Microsoft.Testing.Platform 2.0.0 or newer
  • Test framework with MTP support (e.g., xUnit v3 (xunit.v3.mtp-v2), MSTest v3, NUnit with MTP adapter)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.0.0 214 3/12/2026