MSBuild Task for PartCover

I continue to lament the dearth of option for Test Coverage in the .NET world.

In the Java world you have open source tools like Emma and Cobertura that are widely used and supported (and many more) as well as proprietary tools like Clover available.

.NET we have an open source NCover SF that requires you to do odd code instrumentation and is essentially dead it seams, another NCover which is proprietary and costs money and PartCover which is open source, but doesn’t seem real active.

Don’t get me wrong, NCover.org is a good option if you are willing to spend the money for it. But with a team of 30+ and a CI server, I’m not sure if I want to drop $10k on it. (NCover up until version 1.5.8 was Free Software (GPL) before it was closed. Who has the source and why haven’t you forked it yet?)

]]>

If you’re not willing to pay that basically leaves PartCover. But of course you want to integrate your code coverage with your automated build. There was no support for MSBuild out of the box, so I decided to build it.

Creating an MSBuild Task

I need to do 2 things to run PartCover:

  1. Register the native PartCover.CorDriver.dll
  2. Execute the PartCover.exe with the proper options

Register Native DLL

To see the details on how to register a native DLL using .NET code so my earlier post Register and Unregister COM DLL from .NET Code.

Execute PartCover

The MSBuild framework provides a ToolTask base class whose whole purpose is for executing external command line tools. I used this as the base of the task.

1. ToolName

First you override the ToolName property to return the name of the EXE to run. Nothing special here, it’s just the executable name.


protected override string ToolName
{
get { return "PartCover.exe"; }
}

2. Properties

Next to start build the task you go about defining all of the settings that a user will need to set to execute the task. You then create those as Properties on the class and they will be set by MSBuild. Start with the simple things that someone will need to pass to get the tool to execute properly. You can build from there for other properties. If possible give the properties sane defaults so that people don’t have to override them in their build file.


// ...

///

/// The application to execute to get the coverage results.
/// Generally this will be your unit testing exe.
///

public string Target
{
get { return _target; }
set { _target = value; }
}

///

/// The arguments to pass to the executable
///

public string TargetArgs
{
get { return _targetArgs; }
set { _targetArgs = value; }
}

public string WorkingDirectory
{
get { return _workingDirectory; }
set { _workingDirectory = value; }
}

// ...

3. Command Arguments

Then you need to override string GenerateCommandLineCommands() method. The whole purpose of this method is to construct any command line parameters that need to be passed to the ToolName command using the Properties defined in the task.


protected override string GenerateCommandLineCommands()
{
StringBuilder builder = new StringBuilder();
AppendIfPresent(builder, "--target", Target);
AppendIfPresent(builder, "--target-work-dir", WorkingDirectory);
AppendIfPresent(builder, "--target-args", QuoteIfNeeded(TargetArgs));
AppendIfPresent(builder, "--output", Output);

AppendMultipleItemsTo(builder, "--include", Include);
AppendMultipleItemsTo(builder, "--exclude", Exclude);

Log.LogCommandLine(builder.ToString());

return builder.ToString();
}

5. Execute

Finally, if you have anything special to do, you can override the Execute(). In this case, I wanted to handle the registering and de-registering of the Core.dll. Make sure that you call the base.Execute() method so that the TaskTarget can do the work that it needs to do.


public override bool Execute()
{
string corDriverPath = Path.Combine(ToolPath, CorDriverName);
Log.LogMessage("CoreDriver: {0}", corDriverPath);
using (Registrar registrar = new Registrar(corDriverPath))
{
registrar.RegisterComDLL();
return base.Execute();
}
}

To see the whole thing, download the files at the bottom of this post.

How to Use PartCover with MSBuild

Now that you have a Custom task you need to create a Target in your MSBuild file to execute the task.









Download the code:
PartCover MSbuild.zip

Good luck and I hope someone else finds this useful.

Mocking .NET Objects with NUnit

NUnit is my Unit Testing tool of choice for .NET development. Microsoft provides a unit testing framework but it only works with some higher-end versions of Visual Studio. They’re so similar that it’s almost ridiculous that Microsoft created their own version.
(See one of my previous posts for more information on Automating NUnit with MSBuild.) In the Java world it’s fairly common to do Mocking to help make unit testing easier. I’ve written about using JMock for Unit Tesing in Java. In this post, I’d like to talk about a relatively new feature of NUnit which now supports Mocks out of the box.

What Are Mock Objects

Mock Objects are a technique that allow you to isolate classes from their dependencies for testing purposes. This isolation allows for fine-grained testing of single methods in a single class, possibly even before the dependent classes are fully implemented. This isolation allows your tests to run quickly and it makes testing small pieces of functionality much easier. When you’ve tested individual pieces of code in isolation you can have much higher confidence in larger-grained tests. This isolation becomes even more interesting when you are dealing with dependencies such as a data layer or a web service layer. External calls like that can be very time consuming or could fail if the remote system is down for maintenance.

One of the great things about using Mock Objects is that they force you to think about the dependencies that your classes and methods have. It forces you to think about the coupling between your classes. If you have high coupling then your code is often harder to test. If you have a loosely coupled design then testing and using Mock Objects is very much easier. Thinking about those design notions early can help you more easily manage change over time.

Maxims:

  • Good design is better than bad design
  • Loosely coupled objects are usually a better design than tightly coupled objects
  • Testing improves code quality and developer efficiency over time
  • Testing is easier with a loosely coupled designs

A Sample Project

We’re going to start with some simple code. We create a Domain object called Person and an interface for a Data Access object called IPersonRepository. Pretty simple at this point.

public class Person
{
public string Id;
public string FirstName;
public string LastName;
public Person(string newId, string fn, string ln)
{
Id = newId;
FirstName = fn;
LastName = ln;
}
}


public interface IPersonRepository
{
List GetPeople();
Person GetPersonById(string id);
}

Next we create a PersonService object. This would represent all of the business logic in our application. It would interact with the Data Access tier and return information to the UI layer for display.

We wire together our objects using Constructor based Dependency Injection. All of the dependent Objects are sent in through the constructor. This allows for the loose coupling since the PersonService doesn’t know about the Implementing class, but only the interface. Since it’s done in the constructor we can also never have an invalid PersonService as would be the case if there was a setter for the IPersonRepository implementation.

This is again a fairly straightforward implementation, but I hope enough to display the issue at hand.

public class PersonService
{
private IPersonRepository personRepos;
public PersonService(IPersonRepository repos)
{
personRepos = repos;
}
public List GetAllPeople()
{
return personRepos.GetPeople();
}
public List GetAllPeopleSorted()
{
List people = personRepos.GetPeople();
people.Sort(delegate(Person lhp, Person rhp) {
return lhp.LastName.CompareTo(rhp.LastName);
});
return people;
}
public Person GetPerson(string id)
{
try
{
return personRepos.GetPersonById(id);
}
catch (ArgumentException)
{
return null; // no person with that id was found
}
}
}

Using Mocks with NUnit

Now we can start testing our PersonService. Notice that we haven’t even implemented the IPersonRepository yet. That way we can make sure that everything in our PersonService class works as expected without having to think about other layers of the application.


using System;
using System.Collections.Generic;
using NUnit.Framework;
using NUnit.Mocks;
[TestFixture]
public class PersonServiceTest
{
// The dynamic mock proxy that we will use to implement IPersonRepository
private DynamicMock personRepositoryMock;
// Set up some testing data
private Person onePerson = new Person("1", "Wendy", "Whiner");
private Person secondPerson = new Person("2", "Aaron", "Adams");
private List peopleList;
[SetUp]
public void TestInit()
{
peopleList = new List();
peopleList.Add(onePerson);
peopleList.Add(secondPerson);
// Construct a Mock Object of the IPersonRepository Interface
personRepositoryMock = new DynamicMock(typeof (IPersonRepository));
}
[Test]
public void TestGetAllPeople()
{
// Tell that mock object when the "GetPeople" method is
// called to return a predefined list of people
personRepositoryMock.ExpectAndReturn("GetPeople", peopleList);
// Construct a Person service with the Mock IPersonRepository
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// Call methods and assert tests
Assert.AreEqual(2, service.GetAllPeople().Count);
}
[Test]
public void TestGetAllPeopleSorted()
{
// Tell that mock object when the "GetPeople" method is called to
// return a predefined list of people
personRepositoryMock.ExpectAndReturn("GetPeople", peopleList);
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// This method really has "business logic" in it - the sorting of people
List people = service.GetAllPeopleSorted();
Assert.IsNotNull(people);
Assert.AreEqual(2, people.Count);
// Make sure the first person returned is the correct one
Person p = people[0];
Assert.AreEqual("Adams", p.LastName);
}
[Test]
public void TestGetSinglePersonWithValidId()
{
// Tell that mock object when the "GetPerson" method is called to
// return a predefined Person
personRepositoryMock.ExpectAndReturn("GetPersonById", onePerson, "1");
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
Person p = service.GetPerson("1");
Assert.IsNotNull(p);
Assert.AreEqual(p.Id, "1");
}
[Test]
public void TestGetSinglePersonWithInalidId()
{
// Tell that mock object when the "GetPersonById" is called with a null
// value to throw an ArgumentException
personRepositoryMock.ExpectAndThrow("GetPersonById",
new ArgumentException("Invalid person id."), null);
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// The only way to get null is if the underlying IPersonRepository
// threw an ArgumentException
Assert.IsNull(service.GetPerson(null));
}
}

The PersonService doesn’t have a lot of logic in it, but I hope this illustrates how you easily can test various conditions using Mock objects. It also illustrates the idea of testing early by allowing you to test some code before all of the dependent objects are implemented.

While the Mocks built into NUnit might not be the most powerful or complete Mocking library out there, it should be sufficient for most uses. I’m sure they will continue to improve them over time as well, so I look forward to them becoming more powerful (and having better documentation) in the future.

Download Code Example:
NMock C# Example Project

For more on NUnit you might like to check out:

More On MSBuild

On the heels of my article on using MSBuild with NUnit, I’ve been totally outdone by Brennan. Check out his series on MSBuild.

He covers Unit testing with NUnit (naturally), but starts with the basics, and gets into everything from Packaging to Web Deployments. All with nice screenshots! He also digs into some things like ItemGroup and CreateItem, which exhibit some rather unintuitive behavior in my opinion.

Check it out…

MSBuild with NUnit

I’ve written about Unit Testing and Build Automation in the past, but mostly dealing with Java projects and tools (because I usually write about things I’m working on at the time). Well, I’ve started a .NET project for the first time in a while so I want to solve some of the samde problems in this environment.

Why MSBuild?

In the Java world, the natural choice for automation is usually Ant. NAnt was created for the as a work alike for the .NET platform and is a very good tool. I’ve build custom extensions for database automation in the past and used it successfully. So why would I consider MSBuild? With the advent of Visual Studio 2005, Microsoft included MSBuild as the build tool for its projects. All of the project files generated by Visual Studio are MSBuild files in disguise. This makes it really easy to leverage the project files to chain together a nice automated build.

Why NUnit?

Microsoft is a true believer in Not Invented Here and as such they created their own Unit Testing framework that looks and acts exactly the same as NUnit. The MS XUnit framework only comes with the higher-end Team System versions of Visual Studio. In addition it is very hard to deploy the DLLs to build systems. The only way to get the proper DLLs installed is to install the full Visual Studio. That seems like a really big problem to me. With NUnit you can include the needed DLLs in your version control system and reference them in the project which makes it very easy to build and test code and use a Continuous Integration process.

How to Integrate MSBuild and NUnit

Here’s the good news, all of the work has been done for you. The good people at Tigris.org (the creators of Subversion) have created a series of MSBuild Tasks filling in the gaps that MSBuild was missing. One of the included Tasks is an NUnit task. Their hard work and the simple script below should get ou started with a build that can run your tests as well.

Example Build File







Debug
bin\$(Configuration)
ProjectName
ProjectNameTest
$(ProjectDir)\ProjectName.csproj
$(ProjectTestDir)\ProjectNameTest.csproj












The “Test” target above uses the NUnit task to run all of the NUnit Tests found in the DLL. There are a number of different ways to create ItemGroups ins MSBuild, all of which are odd and confusing. If anyone has any ideas on what the best practices in this regard, let me know.

One final plug for my favorite Visual Studio plugin, ReSharper. It includes support for NUnit. It will help you create NUnit Tests and then lets you run them and debug them from within your IDE. It’s almost like you have a real IDE all of a sudden!

References

NUnit
MSBuild Tasks
Integrating MSBuild with CruiseControl.NET

Pragmatic Unit Testing in C# with NUnit
NUnit Pocket Reference
Deploying .NET Applications: Learning MSBuild and ClickOnce