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.

Automated Subversion Tagging With MSBuild

I’ve written previously about using MSBuild With Nunit as well as a bit of a Manifesto on Relentless Build Automation. I believe that automating the build and deployment process is a necessary step to ensure the reliable delivery of quality software.

Release Management

One of the things that we as software developers have to do is regularly make releases, either to QA or to a customer. When we make releases we need to be able to continue to develop the software to add new features and fix bugs. Tagging is a safety process that we use in a version control system to allow us to easily get to the code that we used to build a specific release. When you Tag, you can always rebuild that release. So, if weeks or months down the road you need to fix a critical bug, but don’t want to release new features, you can get back to the Tag, create a Branch, fix the bug and release the new build to your users.

How Do We Ensure We Can Recreate Releases

How can we ensure that we will be able to recreate a release that we make to either QA or a customer? Use Automation to Tag your builds when you create them of course.

I’ve contributed a new SvnCopy Task to the MSBuild Community Tasks project which was just accepted and committed. It is currently in the Subversion repository for the project but should be available shortly in an official build. This will allow you to easily automate the process of Tagging or Branching your builds when your release. Subversion uses the Copy metaphor for both Branching and Tagging operations which is different from some other version control systems.

Example:












You can then integrate the process of creating a Tag every time you generate a build by tying together Tasks with dependencies. In the example below, the GenerateTestBuild calls GenerateCabFiles and Tag to automatically build the installer and Tag Subversion with the current revisions number.














Hopefully this will help you get started on some more automation.

Update:
MSBuild Community Tasks version 1.2 has been released containing this code. You can get it here.

Resources

MSBuild Community Tasks
Subversion

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