Getting code coverage from your .NET testing using OpenCover.

Getting code coverage from your .NET testing using OpenCover.

Introduction

OpenCover is a free, open-sourced, code coverage tool for .NET 2.0 and above running on the .NET platform. It supports sequence coverage, branch coverage and has a cover by test facility. Though OpenCover is command line only, a rich HTML UI of the results can be visualized using ReportGenerator.

We will aim to demonstrate how you can use this utility to get visibility into your testing coverage.

Background

OpenCover is currently the only actively developed and maintained open-sourced tool of it's type for the .NET platform but it was not the first, some of the others being:

NCover - Probably the most well-known commercial tool for .NET code coverage started life as an open-source project.

Coverage.eye - Originated at Microsoft and was available on gotdotnet, the repository/sample has since gone and no full mirrors appear to exist (The wayback machine only has the text).

PartCover - This appears to have been created in response to NCover going commercial and though actively used it has limitations e.g. 32-bit only. The original repository is no longer being maintained by its original developers and is now being maintained on github.

Using OpenCover

Preparing for OpenCover

The following steps detail how to download OpenCover (and other supporting tools) from NuGet.

OpenCover is available as a zip or msi download via its bitbucket mirror but for the sake of this article we will use the OpenCover nuget package.

  1. Create a new solution
  2. For that solution "Enable NuGet Package Restore"
  3. Using "Manage NuGet Packages for Solution" add the following packages
  • OpenCover
  • ReportGenerator
  • NUnit.Runners

Once completed you should have a solution with a .nuget folder which contains a packages.config that looks something like the following

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
  <package id="NUnit.Runners" version="2.6.3" />
  <package id="OpenCover" version="4.5.1923" />
  <package id="ReportGenerator" version="1.9.1.0" />
</packages>

Next

  1. Create a C# project (class library) called Sample
  2. Create a C# project (class library) called Sample.Test and reference the Sample project
  3. Use NuGet to add the following package
  • NUnit

Now to add a simple class and method and a test that will exercise that method.

In the sample project add the following class

public class Target
{
    public static void DoSomething()
    {
        try
        {
            Console.WriteLine("I ran!");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}  

In the Sample.Test project add the following class

using NUnit.Framework;
[TestFixture]
public class TargetTest
{
    [Test]
    public void DoSomethingTest()
    {
        Target.DoSomething();
    }
} 

Running tests with OpenCover

OpenCover does not directly execute your tests but instead needs to execute another application that executes your tests in this case we are using NUnit.

First lets create a batch file that we can execute our tests from the command line

..\..\..\packages\NUnit.Runners.2.6.3\tools\nunit-console.exe sample.test.dll /noshadow

This batch file can be added to the Sample.Test project (with Copy to Output Directory set to Copy Always).

Now we can use OpenCover to execute this batch file, again we can add this as a a batch file to our Sample.Test project so that we can execute it on the command line

..\..\..\packages\OpenCover.4.5.1923\OpenCover.Console.exe -target:runtests.bat -register:user -filter:+[Sample]* 

The arguments are:

-target: - used to indicate the target process for OpenCover to execute.

-register:user - used to register the COM objects that OpenCover uses to instrument your assemblies.

-filter: - used to control which assemblies OpenCover will gather coverage data for. The filter is capable of including and excluding assemblies and classes and is actually the same filter format that PartCover uses. The filter is one of the more complex features of OpenCover and more detail is provided with the documentation that is installed alongside OpenCover or in the Usage wiki.

When executed, OpenCover will produce an XML file (default results.xml) that contains all the data related to that test run. To visualize that data we can use ReportGenerator to produce some rich HTML output. ReportGenrator can also be run on the command line

..\..\..\packages\ReportGenerator.1.9.1.0\reportgenerator.exe -reports:results.xml -targetdir:coverage  

If we open the produced coverage output (coverage\index.htm) we can see the visualization of the coverage of our target code.
Capture-cpver
As you can see it is quite simple to understand what code your tests actually cover.

For a real-world example OpenCover is actually used to gather coverage on it's own tests and the results can be seen on the OpenCover build pipeline.


NOTE: This article was originally published on CodeProject Nov 3rd 2013