Open Cover Documentation
Open Cover Documentation
Intro
The following guide describes how to use OpenCover (also available on NUGET and Chocolatey) to
gather coverage statistics of your application.
a) Can handle 32 and 64 bit .NET processes running on the .NET 2 and .NET 4+ frameworks.
b) Will usually handle .net core applications, however only latest versions supported e.g. 2.2,
3.1 and 5.0.
c) Will gather sequence and branch coverage information of your assemblies that match the
filters and for which the PDB files can be found.
d) Can gather coverage reports of Silverlight applications
e) Can gather coverage reports of Windows Service applications.
f) Can record which tests where executing at a particular time when a coverage point was
visited – only MSTest and NUnit supported (requests accepted for others).
Currently OpenCover has no full presentation of results other than the XML output file;
ReportGenerator (also available on NUGET) is currently the recommended tool for visualizing the
results.
NOTE: When there is no PDB for an assembly then no coverage data will be gathered; this is
different to PartCover which will default to IL coverage under this situation but it was considered as
not required as this is supposed to be a code-coverage tool which can relate such coverage to your
code.
Table of Contents
Intro..................................................................................................................................................... 1
Command Arguments ......................................................................................................................... 2
Mandatory ...................................................................................................................................... 2
Optional .......................................................................................................................................... 2
Handling Spaces .............................................................................................................................. 7
Understanding Filters.......................................................................................................................... 7
Examples ......................................................................................................................................... 7
Regular Expressions in Filters.............................................................................................................. 8
Examples ......................................................................................................................................... 8
Running against IIS .............................................................................................................................. 8
Running against an application ........................................................................................................... 9
Sample............................................................................................................................................. 9
Running against a Silverlight application ............................................................................................ 9
Sample............................................................................................................................................. 9
Running against a Service application ................................................................................................ 9
Sample............................................................................................................................................. 9
Using the -excludebyattribute option ................................................................................................. 9
Using the -excludebyfile option ........................................................................................................ 10
Shimming support ............................................................................................................................. 10
Microsoft Moles support .............................................................................................................. 10
Microsoft Fakes support ............................................................................................................... 11
TypeMock support ........................................................................................................................ 11
JustMock support.......................................................................................................................... 11
Build system integration ................................................................................................................... 11
all-users (32-bit) ............................................................................................................................ 11
all-users (64-bit) ............................................................................................................................ 11
single-user ..................................................................................................................................... 11
Reporting .......................................................................................................................................... 11
FAQ.................................................................................................................................................... 12
Why do I have no results? ............................................................................................................. 12
All my tests are failing and I am getting MissingMethodException.............................................. 12
Command Arguments
OpenCover has a number of arguments that can be used to control the code coverage gathering. If
an argument requires spaces then use "’s to wrap the argument, where they are applicable they will
be indicated with an optional syntax [].
Mandatory
["]-target:<target application>["]
The name of the target application or service that will be started; this can also be a path to
the target application.
Alternatively use -? to show command line help, or -version to print the current version and exit.
Optional
["]-targetdir:<path to the target directory>["]
The path to the target directory; if the target argument already contains a path then this
argument can be used to provide an alternate path where PDB files may be found.
Use this switch to register and de-register the code coverage profiler. Alternatively use the
optional user argument to do per-user registration where the user account does not have
administrative permissions.
If access to registry is limited then try the path32 or path64, depending on your application
(32- or 64-bit), to use an alternate method to load the profiler; unfortunately you cannot
profile 32- and 64-bit processes at the same time using these switches.
You should also consider using path32 and path64 options when profiling .net core targeted
applications and .net 4.8 framework.
Alternatively use an administrative account to register the profilers using the regsvr32
utility; this is the recommended option when running on a build server especially if
–register:user does not work.
-returntargetcode[:<opencoverreturncodeoffset>]
Return the target process return code instead of the OpenCover console return code. Use
the offset to return the OpenCover console at a value outside the range returned by the
target process.
-safemode:on|off|yes|no
Use this switch to disable safe mode (default is on/yes). When in safe mode the profiler will
use a common buffer for all threads which may have performance impacts if you code or
tests use threads heavily. When safe mode is disabled, there may on occasions be some data
loss if the runtime closes the application under profile before the profiler has been able to
retrieve the visit count data.
["]-output:<path to file>["]
The location and name of the output xml file. If no value is supplied then the current
directory will be used and the output filename will be results.xml.
Limits the number of visit counts recorded/reported for an instrumentation point. May have
some performance gains as it can reduce the number of messages sent from the profiler.
Coverage results should not be affected but will have an obvious impact on the Visit Counts
reported.
A list of filters to apply to selectively include or exclude assemblies and classes from
coverage results. Filters have their own format ±[module-filter]class-filter. If no filter(s) are
supplied then a default include all filter is applied +[*]*. As can be seen you can use an * as a
wildcard.
NOTE: Also an exclusion (-) filter takes precedence over an inclusion (+) filter.
-regex
-nodefaultfilters
A list of default exclusion filters are usually applied, this option can be used to turn them off.
The default filters are:
-[mscorlib]*
-[mscorlib.*]*
-[System]*
-[System.*]*
-[Microsoft.VisualBasic]*
-mergebyhash
Under some scenarios e.g. using MSTest, an assembly may be loaded many times from
different locations. This option is used to merge the coverage results for an assembly
regardless of where it was loaded assuming the assembly has the same file-hash in each
location.
-skipautoprops
-showunvisited
Show a list of unvisited methods and classes after the coverage run is finished and the
results are presented.
Any assembly found in an excluded folder (or its children) will be ignored, regardless of any
inclusive filter matches.
Exclude a class or method by filter(s) that match attributes that have been applied that have
been applied. An * can be used as a wildcard.
e.g. -excludebyattribute:*.ExcludeFromCoverageAttribute
Exclude a class (or methods) by filter(s) that match the filenames. An * can be used as a
wildcard.
-hideskipped:<skip-value>[|<skip-value>]
Remove information from output file (-output:) that relates to classes/modules that have
been skipped (filtered) due to the use of the following switches –excludebyfile:,
-excludebyattribute: and –filter: or where the PDB is missing.
<skip-value> can be one or more of the following values separated by the | symbol:
e.g. -hideskipped:File|Filter|Delegate
Gather coverage by test by analysing the assemblies that match these filters for Test
methods. Currently only MSTest and NUnit tests are supported; other frameworks can be
added on request – please raise support request on GitHub.
e.g. -coverbytest:*.Test.dll
-log:[Off|Fatal|Error|Warn|Info|Debug|Verbose|All]
Change the logging level, default is set to Info. Logging is based on log4net logging levels and
appenders.
-service
The value provided in the target parameter is the name of a service rather than a name of a
process.
-servicestarttimeout:[1m|23s|1m23s]
Overrides the default time to wait for the profiled service to start. The examples above
correspond to a timeout of 1 minute, 23 seconds and 1 minutes and 23 seconds accordingly.
-oldstyle
Use old style instrumentation – the instrumentation is not Silverlight friendly and is provided
to support environments where mscorlib instrumentation is not working.
-communicationtimeout:<timeout-ms>
Determines how long the profiler and the host wait for communication to complete before
failing. Defaults to 10s. Max to 60s. Only considering increasing if the assembly being
profiled is extremely large.
-ignorectrlc
Instructs the OpenCover console host process to ignore ctrl+c key press, should only be used
when the target application requires the use of ctrl+c to close down.
-enableperformancecounters
Handling Spaces
If your argument needs to escape quotes i.e. to pass arguments with spaces to the target process
then you can use \".
e.g.
Or
Understanding Filters
Filters are core to understanding how OpenCover works and how it is determined which assemblies
are to be instrumented to provide coverage results.
Filters can be inclusive and exclusive represented by + and – prefix respectively, where exclusive (-)
filters take precedence over inclusive (+) filters.
The next part of a filter is the module-filter and usually this happens to be the same name as the
assembly but without the extension and this rule will normally apply 99.999% of the time. If this
filter isn’t working look in the coverage XML and compare the found <ModuleName/> entries
against the filter.
The final part of the filter is the class-filter and this also includes the namespace part of the class as
well.
Examples
+[Open.*]* -[Open.Test]*
Include all classes in modules starting with Open.* but exclude all those in modules Open.Test
+[Open]* -[Open]Data.*
Include all classes in module Open but exclude all classes in the Data namespace.
+[Open]* -[Open]*Attribute
Include all classes in module Open but exclude all classes ending with Attribute.
Examples
+[(Open\..*)](.*) -[(Open\.Test)](.*)
Include all classes in modules starting with Open.* but exclude all those in modules Open.Test
+[(Open)](.*) -[(Open)](Data\..*)
Include all classes in module Open but exclude all classes in the Data namespace.
+[(Open)](.*) -[(Open)](.*Attribute)
Include all classes in module Open but exclude all classes ending with Attribute.
“The trick is to start OpenCover to run the w3wp.exe process in debug mode e.g.
OpenCover.Console.exe -target:C:\Windows\System32\inetsrv\w3wp.exe -targetargs:-debug
-targetdir:C:\Inetpub\wwwwoot\MyWebApp\bin\ -filter:+[*]* -register:user
1. All applications running under the site must make use of the same app pool; you'll get errors
in the EventLog otherwise.
2. inetserver needs to be stopped, before starting w3wp.exe in debug mode. You can use the
following command:
net stop w3svc /y
After testing/code coverage completion you can close the w3wp.exe process and start the
inetserver again:
net start w3svc
Sample
OpenCover.Console.exe -register:user -target:..\..\..\tools\NUnit-2.5.10.11092\bin\net-
2.0\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow" -filter:"+[Open*]* -
[OpenCover.T*]*" -output:opencovertests.xml
Sample
OpenCover.Console.exe -register:user "-target:C:\Program Files (x86)\Internet
Explorer\iexplore.exe" "-targetargs:http://localhost:4128/SampleSilverlightTestPage.aspx "-
targetdir:..\SampleSilverlight\SampleSilverlight\Bin\Debug"
Sample
OpenCover.Console.exe -target:"OpenCover Sample Service" -service –register
NOTE: Rather than use the –register switch, it is usually simpler to use the regsvr32 utility to pre-
register the two profiler assemblies (32 and 64-bit) beforehand.
e.g.
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Property)]
public class ExcludeFromCoverageAttribute : Attribute{}
Then you apply this attribute to the class/method/property that you wish to exclude.
Then you add this attribute to the -excludebyattribute option using namespaces and wildcards
where necessary.
e.g.
-excludebyattribute:*.ExcludeFromCoverage*
NOTE: Use with care as you could exclude a method which you should be testing; also it can become
too tempting to ignore a method and not test due to it being difficult and use this option to ‘skip’ it.
e.g. the following would ignore all code in files ending in generated.cs
-excludebyfile:*\*.generated.cs
NOTE: Use with care as you could exclude a method which you should be testing; also it can become
too tempting to ignore a method and not test due to it being difficult and use this option to ‘skip’ it.
Shimming support
In computer programming, a shim is a small library that transparently intercepts API calls and
changes the arguments passed, handles the operation itself, or redirects the operation elsewhere.
Shims typically come about when the behavior of an API changes, thereby causing compatibility
issues for older applications which still rely on the older functionality. In such cases, the older API
can still be supported by a thin compatibility layer on top of the newer code. Web polyfills are a
related concept. Shims can also be used for running programs on different software platforms than
they were developed for.
- wikipedia
Depending on the provider of the Shimming utility will determine on how the OpenCover will be
used alongside it:
TypeMock support
The developers at TypeMock added OpenCover support several years ago; please review their
documentation to get both TypeMock and OpenCover to work correctly with the versions you have
installed.
JustMock support
The developers at JustMock have also added support for OpenCover; please review their
documentation to get both JustMock and OpenCover to work correctly with the versions you have
installed.
To assist your build environment when you install OpenCover using the MSI it will store in the
registry a location of the installation folder. The location in the registry depends on whether it is a
single-user or an all-user installation and also if you are on a 32/64 bit environment.
all-users (32-bit)
Registry Entry: HKLM\Software\OpenCover\Location
Install Location: %PROGRAMFILES%\OpenCover
all-users (64-bit)
Registry Entry: HKLM\Software\Wow6432Node\OpenCover\Location
Install Location: %PROGRAMFILES(X86)%\OpenCover
single-user
Registry Entry: HKCU\Software\OpenCover\Location
Install Location: %LOCALAPPDATA%\Apps\OpenCover
Reporting
It is recommended that ReportGenerator (also available on Nuget) is used to view the coverage
results however if you want to make your own reporting then a sample XSLT has been made
available by Pavan Tiwari (https://github.com/pawan52tiwari). It is simple to use with the supplied
powershell script.
powershell -noexit -file ..\..\transform\transform.ps1 -xsl ..\..\transform\simple_report.xslt
-xml opencovertests.xml -output simple_output.html
The usual reason for no results because OpenCover cannot locate the PDBs for assemblies that
match the filters to be profiled i.e. gather coverage results from. When each assembly is loaded the
location and reason the assembly wasn’t profiled is provided in the coverage results file e.g.
<Module skippedDueTo="Filter" hash="0C-69-37-C2-8F-AB-FC-E7-72-51-E9-17-19-99-1A-4A-4C-07-72-08">
<FullName>C:\Personal\opencover.git\working\main\bin\Debug\OpenCover.Test.dll</FullName>
<ModuleName>OpenCover.Test</ModuleName>
<Classes />
</Module>
The two most common reasons provided are Filter and MissingPdb.
Filter is obviously connected to the –filter: argument and that the ModuleName was not
matched.
MissingPdb is usually because the PDB is not where the assembly is being loaded from. The most
common reason is due to test tools such as NUnit or MSTest which copy the assembly under test to
a new location; this can be corrected by either using the /noshadow or /noisolation option. An
alternative is to use the –targetdir: argument to provide an alternative location for OpenCover to
use.
The other reasons are only applicable to classes and are related to the use of
–excludebyattribute: and –excludebyfile: options.
The profiler assemblies are COM objects and need to be registered in the Registry before the target
process is run.