Cherian Thomas

Friend | Co-founder of Cucumbertown| Cook | I make beautiful things that keep me up all day & night
1 May 2009

Integrating NCover 1.5 with Nant builds

Getting NCover to work with nant builds was more messy than I assumed. What’s more appalling about all this is that programmers new to NCover download it from the default NCover landing page, only to find that its a paid version(3)(version 1.5 is sufficient for most use cases and serves most of the purposes.)

Another concern was that most of the the ncover tutorials on the web showed how to test a single unit test assembly even though ncover comes with a nunitproject nant task to pick out multiple test files(which is the highway case).

Without much further ado, here’s what I did

Download version 1.5.8 of NCover, v 1.4 of NCover Explorer and v 1.4 of NCover Extras

NCover Extras encapsulates the functionalities provided by NCover as a set of nant tasks. This needs to be loaded.Also CoverLib.dll that comes with NCover needs to be registered.

<loadtasks assembly="${ncover.nant.task.dir}NCoverExplorer.NAntTasks.dll"/>


<exec program="regsvr32" workingdir="${ncover.dir}" commandline="/s coverlib.dll"/>

Add these lines before the target is called.

Now for the actual task…

<target name="coverage">


  <nunitproject project="${output.dir}tests.nunit">


    <fileset basedir="${output.dir}">


        <include name="*.*Test*.dll" />














    commandLineArgs="${output.dir}tests.nunit /nodots /nologo"










    <assemblies basedir="${output.dir}">


      <include name="CompanyName*.dll" />


      <exclude name="*.*Test*.dll" />


























    satisfactoryCoverage="80" >




      <include name="${coverage.reports.dir}Unit.Test.Coverage.xml" />






      <exclusion type="Assembly" pattern="*.Tests" />


      <exclusion type="Namespace" pattern="*.Tests*" />







The node with the nunitproject picks all the test dll’s from the output directory and builds a tests.nunit project file. This will be the input to Nunit which NCover will profile.

Digging into the NCover node you’ll see how NCover is being instructed to take pick the assemblies. If you are copying the code verbatim then change the assemblies node to pick your project dll’s and avoid test dll’s(By convention test assemblies are named ProjectName.Tests.dll). The output of this profiling task will be an xml file(Unit.Test.Coverage.xml in this case) which will be the input to NCoverExplorer, to get those fancy html outputs.

Here’s a typical NCover output xml..


The next node ncoverexplorer takes the xml files and builds a html output. Something similar to what’s shown below. Additionally the attribute failMinimum(not shown in this case) will fail the build if coverage doesn’t meet the coverage percentage specified.

Here’s a sample output.


One little quirk I encountered here was using nunit-console.exe instead of nunit-console-x86.exe. My 64 bit Server 2008 build machine rejected the first executable outright since it ran as 64 bit.

What pissed me of in this exercise was the time it took to integrate a seemingly simple open source project. Pretty much the same experience I had dealing with DD-WRT firmware sources. Once the author/company decides to to release a higher version of the project as a paid version or to make money out of the project, they then obfuscate source paths or put in obstacles that deter consumers from downloading those open source versions.

In case of the DD-WRT the source was hidden inside GB’s of data and in this case the official NCover website removed all the forums and added nag screens asking users to signup(given below) before downloading..


  • Pingback:

  • Eric

    So were you able to build a 64-bit version of CoverLib.dll? AFAIK, the version that comes part of 1.5.8 isn’t 64-bit compatible. And, AFAIK, this is the only reason NCover 1.5.8 isn’t 64-bit compatible.

    If you did build it, can you post it for download?

  • admin

    @Eric. No I didn’t build a 64 bit. The dll by exe by itself ran in 64 bit mode(which obviously didn’t work for me)