Running Coverage Analysis from the Command Line
dotCover console runner is a command-line tool included into the dotCover distribution package. The tool allows you to:
- Control execution of any test runner (MSTest, NUnit, xUnit, MSpec, etc.) and record coverage of executed tests in coverage snapshots.
- Merge coverage snapshots.
You may need to merge snapshots if, for example, you use several different formats of unit tests in your project or solution. In this case, you will have to start console runner for all corresponding test runners and get several coverage snapshots. Then, you can use the merge command to merge the snapshots.
- Generate coverage reports in different formats.
Use report command to generate reports in desired formats from coverage snapshots.
Next in this topic, you will find several walkthroughs that would help you understand how to perform coverage analysis of your unit test projects using the Console Runner.
Setting up Console Runner
To set up dotCover Console Runner on a server
- Do one of the following:
- In Visual Studio, go to Get Server Package. dotCover will generate an archive with all necessary files. and click
- Download dotCover command line tools package from JetBrains website.
- Copy the archive to the machine where you are going to set up the Console Runner.
- Extract files from the archive to a directory, from which you are going to start the Console Runner executable file (dotCover.exe).
Optionally, you can add the path to the Console Runner executable as a system path to make the
dotCover command available everywhere.
The following procedure illustrates the simplest case of running coverage with the Console Runner.
To cover a Single Unit Test Project
- Build your unit test project.
- Navigate to the directory where dotcover.exe is located.
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"
- 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, e.g.,
... /TargetArguments="\"D:\My Projects\My Application\bin\Debug\AppTests.dll""
- Output is the report file name.
- ReportType is the type of the report (in this case, we generate an HTML report)
- When the Console Runner exits, the
AppCoverageReport.htmlfile should appear in the same directory with the dotCover console runner. Open this file to explore the coverage results in your web browser.
- Alternatively, you can pass parameters in an XML file. To do so, type
dotcover help cover coverage.xmlin the command line.
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>
dotcover cover coverage.xmlto run the coverage with the specified parameters.
Using dotnet.exe to run coverage analysis of unit tests
There is also a simpler way of using the dotCover console runner. Thus, you can run coverage analysis via the general Microsoft driver:
dotnet.exe. The main benefit of using it is that you do not need to specify an absolute path to a unit test runner, a path to a
.dll with tests, and others. All you have to do is to open the working directory of your project and run:
dotnet dotcover test
To run coverage analysis of unit tests in a project via the dotnet tool (steps 1-4 are made once per project)
- On the official nuget.org site, find the JetBrains.dotCover.CommandLineTools package.
- Do not reference this package in your unit tests project. Instead, open its
.csprojfile and add a line that contains the package name and its version into the
ItemGroupelement. For example:
<ItemGroup> <DotNetCliToolReference Include="JetBrains.dotCover.CommandLineTools" Version="2018.2.0" /> <ItemGroup/>
- In the command line, go to the directory containing your unit tests project.
- Run This will download dotCover command line tools to your computer.
- Run tests with coverage analysis:
dotnet dotcover test
- The suggested way of using the console runner is not a replacement but an addition to dotCover.exe.
- If you want to specify any argument you've used before with dotCover.exe, you can do this by simply adding the
dcprefix to the argument name. E.g., to specify a report type, use
dotnet dotcover test --dcReportType=XML
- If you configured dotCover.exe via an XML file and want to continue using it, specify a path to the file: All parameters in the XML file that are not applicable to this runner type will be ignored.
dotnet dotcover test --dcXML="C:\config\config.xml"
If the coverage report contains some information that you are not interested in, you can apply filters, which tell the Console Runner, what should be included or excluded from the coverage report.
You can specify include and exclude filters in any order. Independently of the order, Console Runner first applies include filters and then exclude filters.
If no include filters is specified explicitly, Console Runner first includes everything and then excludes what specified in exclude filters.
If there is some include filter, then Console Runner first excludes everything that does not match to include filter, and then applies explicit exclude filters, if any.
By default, whether you specify any exclude filters or not, Console Runner adds the following filters for system assemblies:
If necessary, you can disable these default filters with the
DisableDefaultFilters command-line parameter.
There are two ways to specify coverage filters:
To set up coverage filters using XML configuration file
- 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>
<ModuleMask>AdditionalTests</ModuleMask>- all tests from the corresponding module will be excluded.
AdditionalTestshere is an assembly name without extension.
<ClassMask>MainTests.Unit*</ClassMask>- all classes whose name starts with
MainTests.Unitwill be excluded.
<ClassMask>MainTests.IntegrationTests</ClassMask> <FunctionMask>TestFeature1</FunctionMask>- the
TestFeature1method of the
MainTests.IntegrationTestsclass will be excluded. Note that
FunctionMaskmust 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
ClassMaskin this particular case, dotCover will exclude all
TestFeature1methods (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.ExcludeFromCodeCoverageAttributeattribute, we can add the following to the coverage.xml configuration file:
... <AttributeFilters> <AttributeFilterEntry> <ClassMask>System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute</ClassMask> </AttributeFilterEntry> </AttributeFilters>
Alternatively, you can set up coverage filters using dotCover.exe command-line arguments.
To set up coverage filters using command-line arguments
- To exclude/include items from the coverage analysis, you should run the console runner with the
/Filtersparameter. 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 from above. 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
dotCover.exe cover ... /Filters=-:AdditionalTests;
- To filter out classes and methods based on their attributes, you should use the
/AttributeFiltersparameter. For example, to filter out methods marked with the
dotCover.exe cover ... /AttributeFilters=System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute;
The semicolon (;) works as a separator.
Changing scope of coverage results
By default, when the coverage snapshot is ready, it only includes information on assemblies that were loaded for analysis, i.e. 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.
Covering 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 full path to each assembly, you could use the TargetWorkingDir parameter when specifying test assemblies. E.g.:
<?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, sometimes this approach may not work. For example, when unit test projects use different unit testing frameworks. In such cases we can breakdown the coverage, merging and reporting into individual steps.
Let's suppose that 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:
To run coverage for multiple projects in separate steps
- Create two configuration files for running the cover (c) command on each of the tests projects. testProject1.xml for the TestProject1 that uses MSTest: and testProject2.xml for the TestProject2 that uses NUnit:
<?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>
<?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>
- Run the
cover (c)command on each of the tests projects using the prepared configuration files:
dotcover c testProject1.xmland
dotcover c testProject2.xml. As a result you'll get two coverage snapshots,
- 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>
- 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>
Finding 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_PATHenvironment 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 command:
- Use the
SymbolSearchPathsparameter 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 (e.g. srv*C:\LocalSymbols*http://symbolserver:33417/).
- Use the
AllowSymbolServerAccessparameter to allow dotCover access symbol servers specified either in the
SymbolSearchPathsparameter, or in