27 October 2007

NUnit vs. MbUnit

by mo

Can’t we all just get a long? A couple weeks ago I was asked why I preferred using MbUnit over NUnit… and i realized the question kind of stumped me. Did I choose MbUnit or did I just start using because everyone else is?

So why do I like MbUnit? I think the first reason is this… I’m glad the Unit Runner support for MbUnit is limited. I know there’s a plugin some where that allowed you to debug your MbUnit unit tests in version 2.* of JetBrains Unit Test Runner. But since 3.0 came out it’s been difficult to do, and I’m kind of glad!

My dependence on the debugger is becoming less and less. Admittedly, in the current project I seem to be running the debugger more because of my on going battle with Crystal Reports, but that’s another story. I’ve found that since I started using MbUnit, I’ve spent less time using the debugger and more time developing new functionality. At first there was definitely a stunt in development when learning to work without the debugger, but I’m getting better on not relying on it, and i feel good about it.

I like the MbUnit reports… you can take your pick of text, html, xml or dox. The text report is great for getting quick feedback to see if your tests have passed or if you need to walk through the stack trace to find out where tests have blown up. (Just give me the line #) I haven’t completed figured out what the “dox” report type is supposed to be used for or if it has any relationship to “doxygen”, a great documentation generation tool I used to use during my days of C development (Thank you Mr. Mark!). But I like the report that it generates. It writes out the names of the tests so that they read almost like plain English. Here’s an example:

  • merchandise,should_ have_ 1 0_ percent_ sales_ tax

In the above example, “merchandise” was the name of the class and “should_ have_ 1 0_ percent_ sales_ tax” is the name of the test. Pretty clear and easy to read, it definitely describes the intent of each test nicely!

Combining the “/sr” (show report) switch with a command line build and a readable report makes for some quick development and quick feedback. It’s awesome when you can bang out code, run a build quickly and get quick descriptive response to help you.

Next up… I’m liking the “RowTest” attribute. When it comes to triangulating tests against your subject under test, this attribute can come back handy. Take this for example:

  [Row( 12.49 )]
  [Row( 0.85 )]
  [Row( 9.75 )]
  public void Should_Calculate_0_Percent_Tax_On_Item( double forPrice ) 
    AssertAreEqual( 0, CalculateTax( forPrice, ZeroPercent ) );

Instead of having to write out 3 different tests, or jamming the 3 different assertions into a single test, I can make use of the “RowTest” attribute to ensure my subject is behaving as I expect it to. Pretty nice!

Next up, the Rollback attribute… when you decorate your test method with this little attribute it rolls back any changes made to a database. This comes in quite handy for an integration test against a database. Now you can also make use of the TransactionScope type as while and roll out your own base class for data access tests, but I like that this is baked right in to the unit testing framework. Although, I admit I have not spent much time using this feature yet.

One of the cool new features in the latest version of NUnit is a new “That” method, which allows you write more readable assertions. For example:

  Assert.That(new Money(expected), Is.EqualTo(actual));

Right now it seems that integrating NUnit with other tools like CruiseControl is much easier and supported more, since it is the de-facto standard for unit test frameworks, but spending time trying to figure out how to get MbUnit to get along with others tools help you to get a better understanding of how each tool works and how they work with others.

Either way, I can’t say I’m biased to either MbUnit or NUnit. I think they’re both great unit testing frameworks and I’m glad that they’re around and free to use.

tdd csharp