Fun With NUnit 2.4 and Extension Methods

Published 21 September 07 12:45 AM

It's been a while since I played with NUnit.  This is mainly due to the chip that *they* implanted in my head that gives me a migraine when I stray from VSTS unit tests.

NOTE: at this point, you may be wondering - if that's the case, how were you able to write this blog entry.  Red wine, dear friends, red wine...

So like I was saying, I was playing with NUnit 2.4.3 tonight and wanted to point out a few things that were new to me - and then show you how I took one new feature just a bit further by using new language features in Visual Studio 2008.

First, a few things that I thought were cool in NUnit 2.4.  Note that some of these things have been around earlier than 2.4.x - but I didn't know about them - therefore, they're new <g>.

  • ExpectedExceptionAttribute now allows for pattern matching (even regular expressions) on the error message – Here's the downside.  While supported in the NUnit GUI and console runners, it’s NOT supported in the R# VS Runner – ARRGGGHHHH!!! Please go to the JetBrians JIRA site and vote that this gets fixed ASAP!!
  • Explicit attribute – causes a test or test fixture to be ignored unless specifically selected for running – this seems kind of handy in some cases, but with R# test sessions, I can’t imagine needing it all that much.
  • PlatformAttribute – man, how did I miss this one? Allows you to specify tests that will only be run if the platform condition is satisfied (exclude property allows the converse)
  • PropertyAttribute – new to 2.4 – curious about playing around with this.  If anyone has some specific use cases where this has come in handy, please share!
  • SetCultureAttribute – great way to handle test cases where business logic varies by region.
  • SetUpFixtureAttribute – specified on a class and essentially allows for the class to provide global TestFixtureSetup and TestFixtureTeardown functionality to all TestFixtures within a given namespace. I’m really interested in getting a better idea on what was the use case for creating this feature.  Again, if anyone has specific use cases where this has proven invaluable, do tell.
  • New way of doing assertions (constraint-based) seems like a syntax that puts us on the path towards a more natural expression.

And on that note...

I was really enamored with the new syntax for assertions.  To give you a more concrete example.  Take the following NUnit 2.x test to compare ages.

[Test]
public void IsOlderTestNUnit2x() {
    Person howard = new Person("Howard", "Dierking") { 
        Birthday = new DateTime(1977, 3, 11) };
    Person jenn = new Person("Jennifer", "Dierking") { 
        Birthday = new DateTime(1976, 3, 3) };

    Assert.Less(jenn.Birthday, howard.Birthday);
}
 
Pretty simple.  However, the syntax here forces you to slow down a bit and consider the order of parameters - put another way, the syntax flattens the logical flow of the expression.  NUnit 2.4 adds a new way of expressing assertions that is a bit closer to natural language - check out the constraint-based approach...
 
[Test]
public void IsOlderTestNUnitConstraint() {
    Person howard = new Person("Howard", "Dierking") { 
        Birthday = new DateTime(1977, 3, 11) };
    Person jenn = new Person("Jennifer", "Dierking") { 
        Birthday = new DateTime(1976, 3, 3) };

    Assert.That(jenn.Birthday, Is.LessThan(howard.Birthday));
}
 
I thought that this was a pretty cool way of representing things.  The one thing that kept bugging me, though was the fact that I still had to use 2 arguments to express what was, to me, one logical idea.  So then I thought, "Hey, wouldn't this be a cool use of extension methods?"  So I fired up my VS 2008 VPC (NOTE TO SELF: Until I have a 4 proc machine with 8 GB of RAM, I will NEVER AGAIN install Vista on a VPC) and tried it out.  The extension methods themselves were incredibly easy.
 
public static class SyntaxHelperExtensions
{
    public static bool IsGreaterThan(this IComparable expected, IComparable actual) {
        return expected.CompareTo(actual) > 0;
    }

    public static bool IsLessThan(this IComparable expected, IComparable actual) {
        return expected.CompareTo(actual) < 0;
    }
}

And the result?  As advertised, 1 baby step closer to a more natural expression of my test.

[Test]
public void IsOlderTestExtensions() {
    Person howard = new Person("Howard", "Dierking") { 
        Birthday = new DateTime(1977, 3, 11) };
    Person jenn = new Person("Jennifer", "Dierking") { 
        Birthday = new DateTime(1976, 3, 3) };

    Assert.That(jenn.Birthday.IsLessThan(howard.Birthday));
}
 
Now to just get some new keywords in the language!

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# aaron said on September 22, 2007 9:41 PM:

On the Vista thing... looks like you're not the only one!

http://www.engadget.com/2007/09/21/microsoft-giving-vista-business-ultimate-users-downgrade-to/

# danthony said on September 24, 2007 12:51 PM:

Thanks H, you just reminded me of how old I am getting:

Birthday = new DateTime(1977, 3, 11) };

# hdierking said on October 16, 2007 12:37 AM:

As a quick follow up, I had a conversation with Jim Newkirk at the ALT.NET conference around this more fluid-interface style of unit test assertions - and I was a little surprised when he told me that he really wasn't a big fan.  His reason made a lot of sense, however - that this style of assertions is processed essentially left to right while a more natural (or at least familiar) style of evaluating such expressions takes into account the standard order of operations.

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

About hdierking

I am currently the Editor-in-Chief for MSDN Magazine. I joined Microsoft in 2006 as a product planner with the certification team at Microsoft Learning. Prior to that, I spent my career as a developer and later as an architect. My main technology passions include pretty much anything on language theory, agile development, and service-oriented architecture.
Page view tracker