Recently I noticed ReSharper’s built-in test runner doesn’t require you to decorate your fixtures as TestFixture — it’s smart enough to locate Test methods regardless. My team noticed this too, and as a result we’ve started to omit TestFixture entirely.

Turns out this is a big mistake. NUnit itself requires them — in our case, we discovered our build server (which calls NUnit directly) was ignoring a large number of tests (including some that were failing), and was reporting much lower code coverage results than expected.

So, somehow we need to enforce that the TestFixture attribute is applied everywhere it should be, so us lazy ReSharper developers don’t miss anything. Not to worry… we can write a test for that!

[TestFixture]
public class MissingTestFixtureAttributeTests
{
    [Test]
    public void All_test_fixtures_must_have_test_fixture_attribute()
    {
        IEnumerable<Type> badFixtures =
            from t in Assembly.GetExecutingAssembly().GetTypes()
            where HasTests(t)
            where IsMissingTestFixtureAttribute(t)
            select t;

        ErrorIfAny(badFixtures);
    }

    static bool HasTests(Type type)
    {
        var testMethods =
            from m in type.GetMethods()
            from a in m.GetCustomAttributes(typeof (TestAttribute), true)
            select m;

        return testMethods.Any();
    }

    static bool IsMissingTestFixtureAttribute(Type type)
    {
        var attributes =
            from a in type.GetCustomAttributes(typeof (TestFixtureAttribute), true)
            select a;

        return !attributes.Any();
    }

    private static void ErrorIfAny(IEnumerable<Type> fixtures)
    {
        if (!fixtures.Any())
            return;

        var sb = new StringBuilder("The following types are missing [TestFixture] attributes:");
        sb.AppendLine();
        foreach(Type type in fixtures)
        {
            sb.AppendLine();
            sb.Append(type);
        }

        throw new Exception(sb.ToString());
    }
}
May 13th, 2010 | 2 Comments

This week I attended a talk where some people were discussing techniques for unit testing private methods — they were going on about problems they had getting something called Private Accessors to work with ReSharper.

The tools they mentioned were completely foreign to me, and I wondered why I’d never heard of them. I think the reason is because I never bothered trying to test a private method before.

I take the approach that, if you have a private method worthy of having its own tests, then it is worthy of being extracted to a public method on a new class. Tests for private methods are a big smell you have an SRP violation somewhere. And they will be brittle anyway so just don’t do it!

October 31st, 2009 | 2 Comments

We’ve been using Udi Dahan’s excellent Domain Events pattern in a project at work. It’s best to keep them as coarse-grained as possible, but we have already identified a dozen or so events that need to be raised by the domain and processed by our services layer.

Naturally, however, I am forgetting to register some of the event handlers in our IoC container. So, as before with our domain services, I decided to write some integration tests to check everything is set up properly. This is very simple to achieve using NUnit’s trusty parameterized tests, ServiceLocator and a sprinkling of generics:

IEnumerable<Type> GetDomainEvents()
{
    var domain = Assembly.GetAssembly(typeof(Employee));

    return domain.GetTypes()
        .Where(typeof(IDomainEvent).IsAssignableFrom)
        .Where(t => !t.Equals(typeof(IDomainEvent)));
}

[Test]
public void Should_be_able_to_resolve_handlers_for_domain_event(
    [ValueSource("GetDomainEvents")]Type @event)
{
    var handler = typeof (IHandles<>).MakeGenericType(@event);

    ServiceLocator.Current.GetAllInstances(handler).Should().Not.Be.Empty();
}

This reveals a nice todo list of all the handlers we haven’t implemented yet. And the ones I forgot to register!

NUnit Should_be_able_to_resolve_handlers_for_domain_event

August 31st, 2009 | No Comments Yet

In code, the Law of Demeter (aka the one-dot rule) is a principle that basically states:

void DoSomething(IFoo foo)
{
    foo.GetStatus(); // good
}

void DoSomething(IFoo foo)
{
    foo.Profile.GetStatus(); // bad
}

In this example, DoSomething() knows intimate details about what an IFoo’s insides look like. This is bad because it’s additional coupling that will bog us down later — if we ever want to change the internal composition of IFoo, we will have to also update all pervert methods like DoSomething() that depend on it.

In some situations, this rule really doesn’t matter, e.g. for trivial or built-in types (datasets come to mind). But other times we definitely want to avoid it. One trick I have discovered for identifying trouble spots is a code smell you might encounter when isolating something for unit testing:

var foo = new Mock<IFoo>();
var profile = new Mock<IProfile>();
profile.Setup(p => p.GetStatus()).Returns(/* the thing we are testing */);
foo.SetupGet(f => f.Profile).Returns(profile);

DoSomething(foo.Object); // assert etc 

Does this code look familiar? In it we are setting up two mocks:

  • The Profile instance, which has a method we want to stub out and verify
  • The parent IFoo, which only exists to return the child Profile

The code smell is all the extra setup cruft required — two levels of nested mocks for just one parameter we are testing. If we do move method and provide a GetStatus() method on IFoo (that internally delegates to Profile), our test immediately becomes a lot clearer:

var foo = new Mock<IFoo>();
foo.Setup(p => p.GetStatus()).Returns(/* the thing we are testing */);

DoSomething(foo.Object); // assert etc 
August 26th, 2009 | 3 Comments

Here is a little convention I have adopted for check-in comments when fixing red lights in NUnit:

Red traffic light

  • A failing test is when the issue lies in production code. It fails because the code it is testing has bugs or isn’t fully implemented to spec yet.
  • A buggy test is when the test itself has an issue, and the production code is totally fine. For us these most commonly occur when we forget to set something up e.g. null test objects or unconfigured mocks.
  • A deprecated test fails because the behaviour of the code is now intentionally different than before, and the assertions it makes are no longer valid.

A fourth, more insidious case is the missing test, where possible paths through production code exist without any tests that specify what their behaviour should be. If you’re doing TDD this should never happen, but when it does it can be quite difficult to track down. A coverage tool like NCover can help, but only if you miss a whole block or method. Otherwise you need to use your programmer spidey sense and stay on the look-out for uncovered situations.

Hopefully most of your red lights are due to failing and deprecated tests. If you get a lot of buggy or missing ones, then it probably means you are skipping the red step of red-green-refactor.

August 22nd, 2009 | No Comments Yet