Please visit NCover Report for updated information.
NCover supports collecting coverage data on Windows Services with the //svc flag. In this article we'll look at collecting and improving coverage for a simple echo service (aptly named "EchoService") written in C#. You can download the sample service and test suite [../assets/EchoService.zip]](assets/EchoService.zip "here"). The test suite uses NUnit, so make sure you have a working install of NCover and NUnit before you try to follow along on your computer.
To install the service, simply run the install_service.bat script on the command line from the folder that it is in. You can also run the uninstall_service.bat script once you're done with this tutorial to remove the service from your computer.
Collecting Coverage With NCover
For our first attempt at coverage, we'll start the service with NCover, wait a few seconds, and then stop it to measure the coverage without any tests. This will help us to verify that coverage is working and set a good baseline for our progress as we begin writing tests.
To run NCover on the EchoService, start it with the following command:
NCover.Console //svc EchoService
You should see output like the following:
Press Control-C on your keyboard to stop collecting coverage. NCover reports around 50% sequence point coverage, which is helpful to keep in mind as you start improving your coverage. NCover writes a coverage.xml file to the current folder, which we can open in NCover Explorer to review the coverage statistics. Open NCover Explorer from the Start Menu and open your coverage file by choosing Coverage File, Open from the toolbar.
If you browse through the EchoService assembly and namespace we see three classes - EchoService, EchoServiceInstaller, and Program. Program provides some plumbing for running the service for us, and it's at 100% coverage just by starting and stopping the service. EchoService does the heavy lifting for the service and is at 68% coverage, so it may be a great spot to focus our attention for testing. EchoServiceInstaller is at 0% coverage, and with good reason, as it's a class for handling installation and uninstallation of the service and has nothing to do with the execution of the service. Since it has nothing to do with runtime, we'll exclude it by right clicking on the EchoServiceInstaller class in the NCover Explorer tree view and choosing "Exclude".
Improving Coverage
Let's write some tests and improve our coverage. In the source you'll find a TestEchoService project with one test fixture written. There's a helper method named EchoMessage that sends a string message to the echo service and returns the result.
For our first test, let's send a message of "NCover is about to blow my mind!" and make sure that we receive it back. Since the EchoMessage method hides communicating with the server from our tests, the test is as simple as:
Assert.AreEqual("NCover is about to blow my mind!", EchoMessage("NCover is about to blow my mind!"));
Let's build the test suite and run it with through NCover to see where our coverage is at. We'll test our service with our test suite while running NCover with the following command line:
NCover.Console.exe //svc EchoService nunit-console TestEchoService\bin\Debug\TestEchoService.dll
This command line runs coverage on the echo service as before, but it also runs our test and stops collecting coverage once the tests have finished running. The coverage file will automatically reload in NCover Explorer, and we can see what parts of the service we need to test further.
If you look at the EchoService class ProcessMessages method, you'll see that one line still remains uncovered. It looks like this particular echo service contains a bit of an Easter egg that returns "Hello, World!" any time "Hello" is received as a message. Let's send "Hello" as a message in another test and make sure it returns "Hello, World!" Here's the source for that test:
[Test]
{
Assert.AreEqual("Hello, World!", EchoMessage("Hello"));
}
The EchoService Dispose method also has one uncovered line. That method was generated automatically by Visual Studio, so we'll trust that it works and exclude it by right clicking on it in the tree view and choosing Exclude from the drop down menu. Let's run coverage one more time and make sure that we're up to 100% by running coverage again and reloading the coverage file in NCover Explorer. The coverage is in fact 100% for the EchoService assembly upon reviewing it in NCover Explorer.
Congratulations, you just successfully gathered code coverage for a Windows Service!