NCoverExplorer

NCoverExplorer is a tool that does a great job of displaying NCover's test coverage XML output so that you can quickly make sense of it and put it to good use. To take you through an example, let's imagine I have a struct called PersonName in a C# project called Domain:

using Domain;
using NUnit.Framework;
using System;

namespace Domain
{
   [Serializable]
   public struct PersonName
   {
      private string itsFirstName;
      private string itsMiddleName;
      private string itsLastName;

      public PersonName(string firstName, string middleName, string lastName)
      {
         if (firstName == null || firstName == string.Empty)
            throw new ArgumentException("Cannot pass null or empty firstName argument into PersonName constructor");
         else if(lastName == null || lastName == string.Empty)
            throw new ArgumentException("Cannot pass null or empty lastName argument into PersonName constructor");
         itsFirstName = firstName;
         itsMiddleName = middleName;
         itsLastName = lastName;
      }

      public string FirstName
      {
         get { return itsFirstName; }
      }

      public string MiddleName
      {
         get
         {
            if (itsMiddleName == null)
               return string.Empty;
            return itsMiddleName;
         }
      }

      public string LastName
      {
         get { return itsLastName; }
      }

      public string FullName
      {
         get
         {
            if(this.MiddleName != string.Empty)
               return this.FirstName + " " + this.MiddleName + " " + this.LastName;
            return this.FirstName + " " + this.LastName;
         }
      }

      public string LastNameFirstFullName
      {
         get
         {
            if(this.MiddleName != string.Empty)
               return this.LastName + ", " + this.FirstName + " " + this.MiddleName;
            return this.LastName + ", " + this.FirstName;
         }
      }
   }
}

Now, continuing our example, let's imagine we have a C# project called Test where I keep my NUnit tests, and in that project I have a test fixture called PersonNameFixture:

using Domain;
using NUnit.Framework;

namespace Test
{
   [TestFixture]
   public class PersonNameFixture
   {
      [Test]
      public void ConstructorSetsProperties()
      {
         PersonName name = new PersonName("First", "Middle", "Last");
      }
   }
}

Assuming the dll of the Test project is placed here:

C:\Development\Projects\NCoverExample\Test\bin\Debug\Test.dll

and assuming I have a command-line open and it is sitting in a folder with the NUnit dlls:

C:\Development\Projects\NCoverExample\ThirdParty\NUnit-2.2.8-net-2.0

Then the following command-line directive will put the NCover and NUnit output files in the C:\Coverage folder

ncover.console "nunit-console.exe" "C:\Development\Projects\NCoverExample\Test\bin\debug\Test.dll" /xml C:\Coverage\NunitOutput.xml //a Domain //l C:\Coverage\Coverage.log //x C:\Coverage\Coverage.xml

At this point in the process, given the fact that we have a skimpy NUnit test for the PersonName structure, when you open up the C:\Coverage\Coverage.xml file with NCoverExplorer, you'll see a window like this:

You can now easily see that yes, the test somewhat covers the constructor (75% to be exact!), but it doesn't test any of the properties of the PersonName structure and it doesn't cover any of the "unusual" scenarios of the constructor. Also, you can see in the above NCoverExplorer snapshot that visited code is outlined in light blue and unvisited code in red--which is a very, very handy feature because now you can visually see exactly what code hasn't been visited. If we change the PersonNameFixture to look like the following, we can see we have 100% coverage:

using System;
using Domain;
using NUnit.Framework;

namespace Test
{
   [TestFixture]
   public class PersonNameFixture
   {
      [Test]
      public void ConstructorSetsProperties()
      {
         PersonName name = new PersonName("First", "Middle", "Last");
         Assert.AreEqual("First", name.FirstName);
         Assert.AreEqual("Middle", name.MiddleName);
         Assert.AreEqual("Last", name.LastName);
      }

      [Test]
      [ExpectedException(typeof(ArgumentException))]
      public void NullFirstNameThrowsArgumentException()
      {
         new PersonName(null, "Middle", "Last");
      }

      [Test]
      [ExpectedException(typeof(ArgumentException))]
      public void EmptyFirstNameThrowsArgumentException()
      {
         new PersonName(string.Empty, "Middle", "Last");
      }

      [Test]
      [ExpectedException(typeof(ArgumentException))]
      public void NullLastNameThrowsArgumentException()
      {
         new PersonName("First", "Middle", null);
      }

      [Test]
      [ExpectedException(typeof(ArgumentException))]
      public void EmptyLastNameThrowsArgumentException()
      {
         new PersonName("First", "Middle", string.Empty);
      }

      [Test]
      public void FullName()
      {
         PersonName name = new PersonName("First", "Middle", "Last");
         Assert.AreEqual("First Middle Last", name.FullName);
         name = new PersonName("First", null, "Last");
         Assert.AreEqual("First Last", name.FullName);
      }

      [Test]
      public void LastNameFirstFullName()
      {
         PersonName name = new PersonName("First", "Middle", "Last");
         Assert.AreEqual("Last, First Middle", name.LastNameFirstFullName);
         name = new PersonName("First", null, "Last");
         Assert.AreEqual("Last, First", name.LastNameFirstFullName);
      }
   }
}

And the NCoverExplorer output will look like this:

And now we have 100% coverage, which is a pretty good feeling, indeed.

Much like TDD , NCover and NCover Explorer are two very important tools in my development bag that I will be using on every single project from this point forward.

Click here for more...