Integrate NCover with CC.Net
In previous posts I have covered getting cc.net up and running, combining NUnit reports with cc.net and generating documentation automatically as part of the build process. In this post I want to briefly describe how to get your unit test code coverage integrated with cc.net.
If like me you have a legacy project that you think has been tested to the ends of the Earth and back, you may be in for a shock. There will be sections of your code base that is just not touched by your unit tests. One of the best tools to see where you are missing coverage is NCover. This is a tool which although was once free, you can still get fully functional free versions prior to the project becoming commercialised. These can be downloaded from here. Version 1.5.8 is the one I have been using here. Although it states it is beta, it is fully functional and as far as I can tell, bug free.
There is another tool you may need, although it doesn’t effect our usage with cc.net. This tool is NCover explorer, and like NCover used to be a free product. It is now shipped with the full NCover. Older versions of NCover explorer can be downloaded from Grant Drakes blog here. I have been using version 1.4.0.7.
There are two methods to you using NCover. The first is to attach it to your application and run it. It will analyze all the sections of code which it touches and those it doesn’t touch at all. This is ok if you just want to see if there are any code which is being underused or parts which are overused and could be a potential bottleneck. The second method is to run it against the dll produced from your unit tests. This is the method I will describe as it shows how much coverage your tests give as opposed to how much code the application covers. Don’t be confused all we be clear in a moment.
OK, firstly you need to make sure that your unit tests are compiled to a dll, you can use a Nant script for this. Here is an example of one of my NAnt scripts.
1: <csc target="library" output="nant_build\UnitTests.dll" debug="true">
2: <sources>
3: <include name="..\UnitTests\*.cs"/>
4: </sources>
5: <references>
6: <include name="nant_build\MyApp.dll" />
7: <include name="nant_build\nunit.framework.dll" />
8: </references>
9: </csc>
Without posting the whole script, firstly MyApp is compiled into the nant_build directory, then the above section compiles just the unit tests which are in a separate project in the same solution. One important thing to note is the fact that NCover needs the debug information, so append the debug="true" attribute to the csc command for the MyApp.dll.
Next you need to call the ncover.console.exe and pass it any needed parameters like this:-
1: <exec program="C:\Program Files\NCover\1.5.8\ncover.console.exe"
2: commandline="//reg //w "nant_build" "C:\Program Files\NUnit 2.4.3\bin\nunit-console.exe" UnitTests.dll" />
reg = Registers the CoverLib.dll
w = Working directory
You pass ncover the location of the NUnit console application installed on your machine, and then pass that the location of your unit tests library file. Just remember that this script will be run on a build machine, so you must make sure that all paths are correct. On my development machine I run local nant builds using a file like nant_local.build as opposed to nant.build on the cc.net server. This way I don’t ‘accidentally’ run a script that may publish an application to one of our servers when I don’t want to. I have described how to run a NAnt script from your VS IDE here. When this script is run NCover will generate an XML file called Coverage.xml by default, you can rename it by passing the //xml parameter.
So now the Coverage.xml file is produced you need to display it using cc.net; to do this edit the ccnet.config file. Mine is located at c:\Program Files\CruiseControl.NET\server. Like merging the NUnit results you have to specify the location of Coverage.xml in the <file> element. Now the cc.net documentation states that you can specify multiple xml files in the same <file> element, but I couldn’t get this to display anything, so what I did was to specify the NUnit and NCover results in separate <file> elements like this:-
1: <publishers>
2: <merge>
3: <files>
4: <file>
5: <![CDATA[C:\Projects\MyApp\MyApp\nant_build\test_results\result.xml]]>
6: </file>
7: <file>
8: <![CDATA[C:\Projects\MyApp\MyApp\Coverage.Xml]]>
9: </file>
10: </files>
11: </merge>
12: <xmllogger />
13: </publishers>
Then when a build is run, you get the data integrated in the report like this:-
Clicking on the NCover Report link on the cc.net main menu gives you a more in depth analysis like showing which line numbers in your .cs files have not been visited by your unit tests.
Like I said earlier I was quite shocked, when I first run this a couple of weeks ago I only had 26% coverage. Now I am up to 96% and am trying to cover the edge cases.