Monday, November 19, 2007

NCoverCop trunk... for coverage

If you grab NCoverCop from svn you can check out a couple of improvements.


  • Refactoring Allowed.. If you delete tested code that is no longer needed, then this will unfortunately have the side effect of dropping your coverage percentage. NCoverCop allows for this by checking the number of untested lines. If it has not increased then the build is passes as you didn't make things worse.

  • Coverage Differences are displayed when a build fails to give you an idea of the lines in the file that have become uncovered, or been added without test.

  • sectionOfFilePathToCompareRegex allows you to specify a section of the document paths in the NCoverResults.xml files to ignore when comparing the files. This allows you to compare the build's file with your local one even if your trunk paths differ.


          coverageFile="${ncover.output.filename}"
minCoveragePercentage="59"
previousCoverageFile="${ncover.backup.filename}"
autoUpdate="${environment::get-machine-name() == debug.buildbox.name}"
sectionOfFilePathToCompareRegex="trunk.*"
/>


E.g. "trunk.*" (as above) will truncate "C:/something/trunk/somedir/file.cs" to "trunk/somedir/file.cs" when comparing with another results file.


Let me know if you find NCoverCop useful.


Note: Big big thanks to VarianInc for allowing me to do some work on NCoverCop on their dime. They have introduced a policy of using opensource code wherever they can, and contributing back to the community.

Varian (Melbourne) are by far the most agile company I have worked for to date. I highly recommend anyone that is keen to be part of a well functioning agile .Net team to get in contact with them. Email me and I'll forward your details if you like.

Unveiling NCoverCop

Duncan Bayne (who I have the pleasure of working with at the moment) had the idea of writing a small exe to parse an NCoverResults file and fail a build if the coverage drops below a set threshold. I loved it... and decided to up the ante.


From that seed I have built NCoverCop.

NCoverCop is a custom NAnt task that not only fails your build if your coverage drops, but lifts the threshold each time a new build passes with a higher threshold.

It works by keeping a copy of the best coverage file.

Here's how I use it..


  
coverageFile="${ncover.output.filename}"
previousCoverageFile="${ncover.backup.filename}"
minCoveragePercentage="65"
autoUpdate="${environment::get-machine-name() == debug.buildbox.name}"
/>


  • coverageFile is the location of the NCoverResults.xml file you want to compare.

  • previousCoverageFile is the file that will be overwitten if a successful build beats the current threshold.

  • minCoveragePercentage is used when you don't have a previousCoverageFile yet or the specified percentage is higher than that of the previousCoverageFile.

  • autoUpdate can be turned off so the previousCoverageFile doesn't get updated in a passing build.[defaults to on]



Here are a few tips...

We have the previousCoverageFile in a location that is visible on the network and referenced in the build file through it's network address. Coupled with being able to turn autoUpdate off for everyone except the build machine means that you can run ncoverCop locally and see if you are going to break the build before you check in.

Friday, November 16, 2007

Get your build fixed faster... broadcast your failures!

We've been talking about setting up a build box light for ages.

The other day my project manager bought a USB Visual Signal Indicator. An hour of hacking .. and we now have a light that's green on a passing build and flashes red on a breaking build.

We are using CruiseControl.Net as our build machine, so I controled the light using a custom build publisher.

The result we are experiencing is the build is gets fixed faster. I have a few theories as to why.

Here is the code...

using System;
using System.Text;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Remote;


namespace FlashLightPublisher
{
[ReflectorType("flashlight")]
public class FlashLightPublisher : ITask
{
[ReflectorProperty("goGreenOnPass", Required = false)] public bool GoGreenOnPass = true;

public void Run(IIntegrationResult result)
{
StringBuilder DeviceName = new StringBuilder(Delcom.MAXDEVICENAMELEN);

int Result = Delcom.DelcomGetNthDevice(Delcom.USBDELVI, 0, DeviceName);

if (Result == 0)
{
throw new Exception("no usb device");
}

uint hUSB = Delcom.DelcomOpenDevice(DeviceName, 0);
switch (result.Status)
{
case IntegrationStatus.Success:
if (GoGreenOnPass)
{
Delcom.DelcomLEDControl(hUSB, Delcom.REDLED, Delcom.LEDOFF);
Delcom.DelcomLEDControl(hUSB, Delcom.GREENLED, Delcom.LEDON);
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDOFF);
}
break;
case IntegrationStatus.Exception:
case IntegrationStatus.Failure:
Delcom.DelcomLEDControl(hUSB, Delcom.GREENLED, Delcom.LEDOFF);
Delcom.DelcomLEDControl(hUSB, Delcom.REDLED, Delcom.LEDFLASH);
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDOFF);
break;
case IntegrationStatus.Unknown:
Delcom.DelcomLEDControl(hUSB, Delcom.BLUELED, Delcom.LEDON);
break;
}

Delcom.DelcomCloseDevice(hUSB);
}
}
}


Our ccnet.config file contains the following snippet...


...
<publishers>
<flashlight/>
...
</publishers>


Note: We have few sequencial builds set up so we don't class the build as green until all the builds have passed. I therefore have all the builds able to make the light go red, but only the last build make it go green.

Wednesday, November 14, 2007

Conduit Design Pattern

I love dependency injection. Specifically I like constructor dependency injection.

Sometimes however you have two objects that need to talk to each other. This means you need create each before the other to use constructor injection.

What I have been doing instead is creating a class I call a conduit.

The Conduit class implements one of the interfaces and delegates to another instance of that interface. It also provies a setter injection method to allow you to initialize the conduit.

To use it therefore you do the following:
1/ Create an instance of IXConduit
2/ create an instance of class Y passing in the IXConduit as an instance of IX
3/ create an instance of class X passing in Y
4/ call the setter injection method on the conduit passing X in.

When Y calls a method on the IX it has (the conduit) it passes on the call the the IX it has (the real instance of X), and X can call method on Y directly.

This means the compilcation of instantiation is not part of class X or Y so they don't get polluted by this design issue.

MockingTestFixture makes NMock tests simpler

I just noticed that not everyone is using a helper class when using NMock2. It seriously makes your code cleaner. Here is the one I use.

using System;
using NMock2;
using NUnit.Framework;


namespace Tests.Utilities
{
public abstract class MockingTestFixture
{
private Mockery mockery;

protected IDisposable Ordered
{
get { return mockery.Ordered; }
}

[SetUp]
public void MockSetUp()
{
mockery = new Mockery();
SetUp();
}

protected abstract void SetUp();

[TearDown]
public virtual void MockTearDown()
{
TearDown();
VerifyExpectations();
}

protected virtual void TearDown()
{
}

public T NewMock()
{
return mockery.NewMock();
}

public void VerifyExpectations()
{
mockery.VerifyAllExpectationsHaveBeenMet();
}

protected static void IgnoreReturnValue(object ignored)
{
}
}
}

Derive your test fixture from this class. Override the abstract setup method... there you go. No more need to worry about the Mockery.

GitHub Projects