dotCover 2023.3 Help

Coverage Analysis from the Command Line

The dotCover command-line tool lets you:

  • Control execution of any test runner (MSTest, NUnit, xUnit, MSpec, and so on) and record coverage of executed tests in coverage snapshots.

  • Merge coverage snapshots with the merge command, for example, to combine snapshots of unit tests that use different testing frameworks.

  • Generate coverage reports in different formats with the report command.

  • and more

The tool is available for Windows (x86, x64, arm64), Linux (x64, arm32, arm64, musl-x64, musl-arm64), and macOS (x64, arm64).

Distribution formats

The tool is distributed in the following formats:

Format

Cross-platform framework-dependent tool


(all OSs, requires .NET to be installed)

Platform-specific self-contained tool


(OS-specific, bundled .NET)

Platform-specific


(Windows only, requires .NET Framework)

Archive

Download page

Download page

Download page

NuGet package

Download page

Download page

Download page

In dotCover 2023.2 and earlier, the command-line tool was also distributed as a separate package which will no longer be maintained.

Install dotCover command-line tool

There are several ways to install the tool.

Recommended if you want to run coverage analysis locally on your computer or a CI/CD server using the dotnet driver.

As a global tool for all projects on the computer

  • Run:

    dotnet tool install --global JetBrains.dotCover.CommandLineTools --version 2023.3.0

As a local tool for a specific project/directory

  • Run:

    dotnet tool install JetBrains.dotCover.CommandLineTools --version 2023.3.0 --tool-path "some/path"

Recommended if you want to run coverage analysis as a build step on a CI/CD server.

  1. Open the required unit test project and add the reference to the JetBrains.dotCover.CommandLineTools package. For example:

    Install-Package JetBrains.dotCover.CommandLineTools -Version 2023.3.0
  2. On your CI/CD server, add a build step that restores NuGet packages.

  3. On your CI/CD server, add build steps that use the command-line tool, e.g., dotnet dotCover.dll ...

The universal way to install the command-line tool.

  1. Download dotCover command line tools package for the required operating system.

  2. Extract the archive.

Configure dotCover command-line tool

You can configure the dotCover command-line tool with command-line parameters or with an XML configuration file. You can use both approaches at the same time. In case of conflicts, command-line parameters override the ones specified in XML.

For example:

dotCover.exe dotnet --output=AppCoverageReport.html -- test "C:\MyProject\MainTests.csproj"
  • Regardless of the tool installation type and the OS, you can use the same parameter syntax, e.g., --TargetExecutable=MyApp.exe

  • Command-line parameters are case-incensitive. E.g., the following is equal: --TargetExecutable=MyApp.exe and --targetexecutable=MyApp.exe

  • You can use slash / and double dash -- to specify a parameter. E.g., the following is equal: --TargetExecutable=MyApp.exe and /TargetExecutable=MyApp.exe

  • You can use equals sign = and colon : to specify parameter value. E.g., the following is equal: --TargetExecutable=MyApp.exe and --TargetExecutable:MyApp.exe

  • Relative paths in command-line parameters are treated relative to the command-line tool working directory.

  • For the full list of parameters, refer to Command Reference.

For example:

dotCover.exe dotnet MyConfig.xml

All dotCover commands (except version and help) can accept parameters in an XML configuration file. The configuration file is a reasonable alternative to specifying all parameters inline or having them in a batch file. To avoid errors in the supported XML tags, we recommend generating a configuration stub file first, and then providing it with your custom parameter values.

To generate a configuration stub file for a particular dotCover command, run:

dotCover help <command name> <configuration stub file>

For example, for the cover command:

dotCover help cover config.xml

Relative paths defined in an XML configuration file are treated relative to the location of this file.

Analyze unit test coverage in .NET projects

There are two ways to run coverage analysis in .NET and .NET Core projects depending on how you installed the command-line tool: using the framework-dependent .NET tool (via the dotnet driver) or the self-contained tool (dotCover.exe, dotCover.sh).

  1. Open the solution folder.

  2. Build the solution:

    dotnet build
  3. Run tests with coverage analysis:

    dotnet dotcover cover-dotnet -- test --no-build

    The dotnet dotcover .NET tool supports the same set of commands and parameters as dotCover.exe and dotCover.sh. For example, to specify a report type, all tools use the --ReportType parameter:

    dotnet dotcover cover-dotnet --ReportType=XML -- test

    If you configured dotCover.exe with an XML file and want to continue using it, specify a path to the file:

    dotnet dotcover cover-dotnet "C:\config\config.xml" -- test

  1. Navigate to the directory where dotCover.exe / dotCover.sh is located.

  2. Type the following command in the console:

    dotCover.exe dotnet --output=AppCoverageReport.html --reportType=HTML -- test "C:\MyProject\MainTests.csproj"

    Here:

    • --output is the report filename

    • --reportType is the type of the report (in this case, we generate an HTML report)

    • -- test "C:\MyProject\MainTests.csproj" at the end is an argument passed to dotnet. Actually, you can replace it with --TargetArguments="test \"C:\MyProject\MainTests.csproj\"" but that is much longer.

  3. After the command-line tool finishes working, it will create the AppCoverageReport.html file in the same directory with the dotCover command-line tool. Open this file to explore the coverage results in your web browser.

Analyze unit test coverage in .NET Framework projects

The following procedure illustrates the simplest case of running coverage with the command-line tool on .NET Framework projects.

  1. Make sure your unit test project is built.

  2. Navigate to the directory where dotCover.exe is located.

  3. Type the following command in the console:

    dotCover cover /TargetExecutable="D:\Program Files\NUnit 2.6\bin\nunit-console.exe" /TargetArguments="D:\Projects\TheApplication\bin\Debug\AppTests.dll" /Output="AppCoverageReport.html" /ReportType="HTML"

    Where:

    • TargetExecutable is the path to the unit testing framework runner

    • TargetArguments are arguments passed to the runner - the compiled unit test assembly. Note that if these arguments contain paths with spaces, you should escape them with additional double quotes and a backslash, for example, ... /TargetArguments="\"D:\My Projects\My Application\bin\Debug\AppTests.dll"\"

    • Output is the report filename.

    • ReportType is the type of the report (in this case, we generate an HTML report)

  4. When the command-line tool exits, the AppCoverageReport.html file should appear in the same directory with the dotCover command-line tool. Open this file to explore the coverage results in your web browser.

  5. Alternatively, you can pass parameters in an XML file. To do so, type dotCover help cover coverage.xml in the command line.

  6. Open the generated coverage.xml file and specify the configuration parameters. For example, the configuration file can look as follows:

    <?xml version="1.0" encoding="utf-8"?> <AnalyseParams> <TargetExecutable>D:\Program Files\NUnit 2.6\bin\nunit-console.exe</TargetExecutable> <TargetArguments>D:\Projects\TheApplication\bin\Debug\AppTests.dll</TargetArguments> <Output>AppCoverageReport.html</Output> <ReportType>html</ReportType> </AnalyseParams>
  7. Use dotCover cover coverage.xml to run the coverage with the specified parameters.

Apply coverage filters

If the coverage report contains some information that you are not interested in, you can apply filters, which tell the command-line tool, what should be included or excluded from the coverage report.

  • You can specify include and exclude filters in any order.

  • Independently of the order, the command-line tool first applies include filters and then exclude filters.

  • If no include filters are specified explicitly, the command-line tool first includes everything and then excludes what specified in exclude filters.

  • If there is an include filter, the command-line tool first excludes everything that does not match to the include filter, and then applies explicit exclude filters (if any).

By default, whether you specify any exclude filters or not, the command-line tool adds the following filters for system assemblies:mscorlib, System, System.*, Microsoft .*.

If necessary, you can disable these default filters with the DisableDefaultFilters command-line parameter.

There are two ways to specify coverage filters: using command-line parameters or using an XML configuration file.

  • To exclude/include items from the coverage analysis, you should run the command-line tool with the --Filters parameter. For example (for simplicity, we omit parameters related to the coverage target):

    dotCover.exe cover ... --Filters=-:module=AdditionalTests;-:type=MainTests.Unit*; -:type=MainTests.IntegrationTests;function=TestFeature1;

    This example is equivalent to the XML configuration example. Note that the semicolon (;) separates not only filter entries but also items inside filter entries.

  • An entry that starts with -: is responsible for excluding, and vice versa, an entry that starts with +: - for including.

  • If you need to exclude/include only a module, you can omit the module keyword:

    dotCover.exe cover ... --Filters=-:AdditionalTests;
  • To filter out classes and methods based on their attributes, you should use the --AttributeFilters parameter. For example, to filter out methods marked with the System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute attribute:

    dotCover.exe cover ... --AttributeFilters=System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute;

    The semicolon (;) works as a separator.

  • To exclude some items (modules, classes, methods) from the coverage report while keeping all others, add the corresponding entries to the ExcludeFilters node. For example:

    ... <Filters> <ExcludeFilters> <FilterEntry> <ModuleMask>AdditionalTests</ModuleMask> </FilterEntry> <FilterEntry> <ClassMask>MainTests.Unit*</ClassMask> </FilterEntry> <FilterEntry> <ClassMask>MainTests.IntegrationTests</ClassMask> <FunctionMask>TestFeature1</FunctionMask> </FilterEntry> </ExcludeFilters> </Filters>

    Here:

    • <ModuleMask>AdditionalTests</ModuleMask> - all tests from the corresponding module will be excluded. AdditionalTests here is an assembly name without extension.

    • <ClassMask>MainTests.Unit*</ClassMask> - all classes whose name starts with MainTests.Unit will be excluded.

    • <ClassMask>MainTests.IntegrationTests</ClassMask> <FunctionMask>TestFeature1</FunctionMask> - the TestFeature1 method of the MainTests.IntegrationTests class will be excluded. Note that FunctionMask must always contain method's short name. If you omit any element in FilterEntry, dotCover will consider this as a wildcard. For example, if you remove ClassMask in this particular case, dotCover will exclude all TestFeature1 methods (belonging to all modules and classes).

  • Alternatively, to include only the desired items while excluding all others of the same kind, add the corresponding entries to the IncludeFilters node.

  • Another option, is to filter out classes and methods based on their attributes. For example, to filter out methods marked with the System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute attribute, we can add the following to the coverage.xml configuration file:

    ... <AttributeFilters> <AttributeFilterEntry> <ClassMask>System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute</ClassMask> </AttributeFilterEntry> </AttributeFilters>

Change scope of coverage results

By default, when the coverage snapshot is ready, it only includes information about assemblies that were loaded for analysis, that is the assemblies that were not filtered out and that have tests. This can make the overall coverage percentage incorrect.

If necessary, you can change the scope of assemblies whose information should be added to the snapshot. To do so, use the Scope parameter. For example, to add all assemblies from your project to the snapshot, you can add the following to the configuration file:

<Scope> <ScopeEntry>ProjectFolder/**/*.dll</ScopeEntry> <ScopeEntry>ProjectFolder/**/*.exe</ScopeEntry> </Scope>

Note that everything excluded with filters is excluded anyway regardless of the specified scopes.

Cover multiple test projects

If there are several unit test projects in your solution, you can run coverage for all of them at once as described in the basic scenario. In this case, to avoid specifying the full path to each assembly, you can use the TargetWorkingDir parameter when specifying test assemblies. For example, with an XML config file:

<?xml version="1.0" encoding="utf-8"?> <AnalyseParams> <TargetExecutable>D:\Program Files\NUnit 2.6\bin\nunit-console.exe</TargetExecutable> <TargetArguments>AppTests.dll AppTests2.dll AppTests3.dll</TargetArguments> <TargetWorkingDir>D:\Projects\TheApplication\bin\Debug</TargetWorkingDir> <Output>AppCoverageReport.html</Output> <ReportType>html</ReportType> </AnalyseParams>

However, this approach won't work if unit test projects use different unit testing frameworks. In such cases, we can break down the coverage, merging, and reporting into individual steps.

Suppose we have two unit test projects, TestProject1 that uses MSTest and TestProject2 that uses NUnit. To run coverage on both projects and get a single report, we perform the following steps:

dotCover: Merging coverages snapshot into a single report

Run coverage for multiple projects in separate steps

  1. Create two configuration files for running the cover (c) command on each of the tests projects. testProject1.xml for the TestProject1 that uses MSTest:

    <?xml version="1.0" encoding="utf-8"?> <CoverageParams> <TargetExecutable>C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\MSTest.exe</TargetExecutable> <TargetArguments>TestProject1.dll</TargetArguments> <TargetWorkingDir>D:\Projects\TheApplication\bin\Debug</TargetWorkingDir> <Output>Snapshot1.dcvr</Output> </CoverageParams>

    and testProject2.xml for the TestProject2 that uses NUnit:

    <?xml version="1.0" encoding="utf-8"?> <CoverageParams> <TargetExecutable>D:\Program Files\NUnit 2.6\bin\nunit-console.exe</TargetExecutable> <TargetArguments>TestProject2.dll</TargetArguments> <TargetWorkingDir>D:\Projects\TheApplication\bin\Debug</TargetWorkingDir> <Output>Snapshot2.dcvr</Output> </CoverageParams>
  2. Run the cover (c) command on each of the test projects using the prepared configuration files: dotCover c testProject1.xml and dotCover c testProject2.xml. As a result you'll get two coverage snapshots, Snapshot1.dcvr and Snapshot2.dcvr.

  3. Run the merge (m) command to merge both snapshots:

    dotCover m merge.xml

    where the merge.xml is the configuration file:

    <?xml version="1.0" encoding="utf-8"?> <MergeParams> <Source>Snapshot1.dcvr</Source> <Source>Snapshot2.dcvr</Source> <Output>MergedSnapshots.dcvr</Output> </MergeParams>
  4. To build an HTML test report from the merged snapshots, run the report (r) command

    dotCover r report.xml

    where the report.xml is the configuration file:

    <?xml version="1.0" encoding="utf-8"?> <ReportParams> <Source>MergedSnapshots.dcvr</Source> <Output>CoverageReport.html</Output> <ReportType>html</ReportType> </ReportParams>

Find symbol files (PDB)

Locating symbol files (PDB) for the target binaries is vital for calculating coverage. If you cover unit tests or cover the startup project, dotCover easily locates symbol files using the structure of the current solution.

By default, dotCover search symbol files in the following places:

  • in the same directory where the binary file resides;

  • in the debug directory that is specified inside the binary file;

  • in all directories specified in the _NT_SYMBOL_PATH environment variable and in the registry;

If necessary, you can specify other places to look for symbol files. To do so, use the following parameters when using the cover or cover-dotnet command:

  • Use the SymbolSearchPaths parameter to provide a semicolon separated list of paths to search for symbol files. Each path can be either a directory path or a symbol server path (for example, srv*C:\LocalSymbols*http://symbolserver:33417/).

  • Use the AllowSymbolServerAccess parameter to allow dotCover access symbol servers specified either in the SymbolSearchPaths parameter, or in _NT_SYMBOL_PATH environment variable.

Last modified: 25 January 2024