NCover Problems / Fixes - Part 1
From time to time I try to chip in with support on the NCover forums, not only with NCoverExplorer issues but NCover as well since they are so dependent. There are a bunch of issues which come up repeatedly, particularly for people new to using NCover.
In a perfect world (future release?) NCover itself could offer some more helpful error messages, but where is the fun in that? For now at least it is more a case of deciphering the clues from the console output and coverage.log files.
Hopefully this series of posts may help a few people and reduce the times I end up repeating myself on the forums, so win-win if it works for you. My examples will use NCover 1.5.7. You should also take a look at the NCover FAQ which is included in your installation. I've got a copy here too if that helps...
Profiled process terminated. Profiler connection not established.
Easily the most common problem people stumble on. As shown below your application starts (in this case unit tests), but after a delay of 60 seconds or so you get this message.
>E:\apps\NCover\ncover.console.exe E:\apps\nunit\nunit-console.exe MyTests.dll
NCover.Console v1.5.7 - Code Coverage Analysis for .NET - http://ncover.org
Copyright (c) 2004-2006 Peter Waldschmidt
Command Args: "MyTests.dll"
Coverage Xml: Coverage.Xml
Coverage Log: Coverage.Log
Waiting for profiled application to connect...
NUnit version 2.2.8
Copyright (C) 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole.
Copyright (C) 2000-2003 Philip Craig.
All Rights Reserved.
OS Version: Microsoft Windows NT 5.1.2600 Service Pack 2 .NET Version: 2.0.50727.42
Tests run: 1, Failures: 0, Not run: 0, Time: 0.016 seconds
Profiled process terminated. Profiler connection not established.
Most likely this is due to one of two reasons I know of:
(1) You are profiling a windows service or IIS - this feature has been reported as currently broken.
(2) You are profiling an executable - but Coverlib.dll was not COM registered
Unfortunately the windows service/IIS testing fell down the cracks for 1.5.7 for those of you trying to use this feature. You can monitor some of the threads on it here and here. Personally for my applications I remove the need to profile services at all. By making the windows service a super lightweight wrapper and moving all the implementation out into classes that are more easily tested there is no need to unit test what remains.
I appreciate however there are scenarios for people where they do want coverage of services for integration testing etc - all I can say for now is that Peter is on the case. Let's now focus on the more common scenario for people trying to profile executables and offer some background info.
So what's that registration bit about then - surely NCover is a .NET application? Sure, some of it is - but the really clever bit of NCover is the C++ implementation of ICorProfiler in Coverlib.dll, which is a callback class for use with the .NET Profiler API. The requirements of the API are that the callback class has to be COM registered and it cannot be written in managed code. By using some environment variables set within NCover before launching your process, the .NET profiler is able to be "switched on" to make the API callbacks while your process is running.
This is the heart of NCover - it monitors the loading of AppDomains and modules, intercepts the JIT execution of methods and injects it's own instructions to monitor the execution counts. This data is then pumped back to the "managed code" part of NCover, which munges the data together to produce the coverage.xml output you know and love for NCoverExplorer to manipulate.
So the "profiler connection not established" message indicates that there was some sort of problem with communication between NCover and the .NET profiler. As illustrated with the windows service problem above this message doesn't always mean that it was caused by a registry problem, but many times it is and it's worth double-checking first.
NCover Installation / XCopy Deployment
If you installed NCover using the MSI installer, then it will have automatically COM registered CoverLib.dll for you in "C:\Program Files\NCover\". If however, you are like many people intending to run NCover using an xcopy style deployment mechanism as with other tools such as NUnit, then you must remember about this requirement.
So let's say you do want to relocate NCover to a tools subfolder in a source controlled directory - what's the idiot-proof way to do it?
Firstly, make sure you copy all the NCover files from the installation folder above. Make sure you don't skip the Microsoft.VC80.CRT.manifest, MSVCP80.dll or MSVCR80.dll files. If you do skip them, then an attempt to register Coverlib.dll will fail on machines without these .dlls already in a path somewhere. You may find it works on your development machine with VS.Net installed, but then fails on your build server.
Secondly, make sure you run the NCover uninstall which will clean up the registry as well as the installed files. So now your machine should be back in "pristine" condition.
Options For Registering NCover
So having identified that when running NCover.Console.exe you need to ensure that Coverlib.dll is registered - what are your options?
1. If you stuck with the default NCover installation, have no need for locating it elsewhere and need only one version of NCover for all your applications. Congratulations - you shouldnt have seen the problem above! If you did, you should manually re-register it using regsvr32 or try running the installer again.
2. The NAnt/MSBuild tasks I provide automatically register and unregister Coverlib.dll on the fly under HKCU. So if using those you are already sorted.
3. If using the command line, NCover 1.5.7 now offers a //reg option. This will do the same as the tasks above of registering and unregistering on the fly.
4. You could invoke regsvr32 on it as part of your script. I suggest you unregister it as well afterwards in case you have multiple NCover versions on your machine to prevent any later confusion.
NCover With TestDriven.NET
I got myself caught out with this little gotcha recently and I'm sure I won't be the last!
As you likely know the excellent TestDriven.Net add-in by Jamie Cansdale includes a copy of (currently) NCover 1.3.3 and NCover 1.5.7 bundled with it. What you probably don't know is under which scenarios it runs which version of NCover and where this can go wrong.
The first thing TestDriven.Net does is check the registry to see if you have installed NCover yourself using the MSI installer. If there isn't then it knows to use one of the versions it has installed. If you have .NET 2.0 installed on your machine it will use the 1.5.x version, otherwise it will use NCover 1.3.3.
If however you do have NCover installed from the MSI, then TestDriven.NET assumes that you want to use that version. Jamie's rationale for this is simple - if you ended up with later versions of NCover on your machine than that supplied with TestDriven.NET then it should use that over it's own.
Where this can go wrong as it did for me is if for some reason you have unregistered NCover in that folder. TestDriven.NET makes the reasonable assumption that if you installed it and left it there then you have it registered there too. However as I dabble with testing and supporting multiple NCover versions all over my drives I had manually unregistered it without remembering to uninstall it. That mistake will then lead to error messages from TestDriven.NET about "Unable to create a coverage report". Either fully uninstall that NCover installation or register CoverLib.dll again in that folder to fix this. My thanks to Jamie for his excellent support!
TypeMock And NCover NAnt/MSBuild Tasks
TypeMock is a very powerful mock objects framework which no doubt some of you are using. Assuming you have purchased the commercial version then you will likely want to be running your tests with code coverage using NCover.
The one gotcha with this is that a requirement of the .NET profiling API is that there can only be one profiler callback registered on a machine when it runs. TypeMock takes care of this by managing the registry itself. However if you use my NAnt/MSBuild tasks then by default they want to "undo" the work of TypeMock by registering NCover, causing a problem.
The solution is available from the 184.108.40.206 build of my tasks in NCoverExplorer.Extras, the latest of which is available here. By adding a registerProfiler="false" attribute to your NAnt task or equivalent for MSBuild the default behaviour of the tasks to register in HKCU is turned off and control is able to be maintained by TypeMock.
That's enough for today. Part 2 will cover the mysterious blank coverage.xml file. Feedback/corrections welcomed - if you have an NCover problem your best bet is to head to the NCover forums.
Filed in: ncover