Once you have a reasonable suite of unit tests, you might start to wonder how much of your code is properly tested. Measuring coverage gives one perspective, and it’s one we can easily add to our builds.
OpenCover is an open-source code coverage tool with a convenient command-line interface that we can easily leverage with Psake.
As we have previously, our starting point is working out how to run the command manually:
(This is quite a mouthful of a command line, so the options are wrapped for readability; if you’re trying this out for yourself, they all need to be on the same line.)
Let’s breakdown the options one by one.
-target: specifies the application to run, in this case, the xUnit console runner for our unit test suite, xunit.console.exe.
-targetargs: defines the arguments to pass to the xUnit console runner. Note the (very easily missed) double quotes here - the -xml and -html options (shown above with an extra indent) are a part of the arguments for xunit.console.exe and therefore part of this string.
-targetdir: specifies the folder where our test assemblies are found; this is needed so that OpenCover knows where to load the required .pdb files. Without this, I find the coverage report shows no coverage at all.
-register: user is needed to activate the profiler if running in an unelevated (non-administrator) mode. Without this, OpenCover needs to be pre-registered via regsvr32.
-output: specifies an output folder for the results of the coverage analysis.
-filter: restricts the reporting to only the assemblies that make up our project; the +[Niche.*]* includes all classes from assemblies starting with Niche.; while -[*Tests]* excludes all our test assemblies.
To set up our build script, we’ll to install OpenCover (via NuGet) and then write a task to find the executable:
Then we can write the task itself:
Lastly, we need to hook it into our continuous integration build:
When we run ci-build.ps1, the output will now include the results of the coverage run:
This is somewhat informative - but fortunately, there’s a lot more information available. We can see details of coverage down to the individual line of code. Next time we’ll see how to generate an HTML coverage report like this one: