October 2008 Entries
Extending exception testing capabilities in NUnit

I was intrigued to read Hadis' post on the exception testing capabilities in xUnit. It's often struck me that the use of attributes on test methods is a bit blunt given the scope for exceptions to be thrown from different locations in test code. After reading how xUnit achieved the testing of expected exceptions I was inspired to implement this in a way that NUnit (and MSTest) could also use. The implementation is really rather simple:

 

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace UnitTestExtensions
   7:  {
   8:      public delegate void ThrownDelegate();
   9:   
  10:      [global::System.Serializable]
  11:      public class ExceptionNotThrownException : Exception
  12:      {
  13:          public ExceptionNotThrownException() { }
  14:          public ExceptionNotThrownException(string message) : base(message) { }
  15:          public ExceptionNotThrownException(string message, Exception inner) : base(message, inner) { }
  16:          protected ExceptionNotThrownException(
  17:            System.Runtime.Serialization.SerializationInfo info,
  18:            System.Runtime.Serialization.StreamingContext context)
  19:              : base(info, context) { }
  20:      }
  21:   
  22:      public static class AssertExtensions
  23:      {
  24:          public static T Thrown<T>(ThrownDelegate d) where T : Exception
  25:          {
  26:              try
  27:              {
  28:                  d.Invoke();
  29:                  throw new ExceptionNotThrownException("Exception of type " + typeof(T) + " not thrown");
  30:              }
  31:              catch (T e)
  32:              {
  33:                  return e;
  34:              }
  35:          }
  36:      }
  37:  }

And a couple of simple tests demonstrate it working:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using NUnit.Framework;
   6:  using UnitTestExtensions;
   7:   
   8:  namespace Tests
   9:  {
  10:      [TestFixture]
  11:      public class NUnitAssertExtensionsTests
  12:      {
  13:          [Test]
  14:          public void Thrown_Catches_And_Returns_Expected_Exception()
  15:          {
  16:              TestClass t = new TestClass();
  17:              ArgumentNullException a = AssertExtensions.Thrown<ArgumentNullException>(()=>t.Chuck());
  18:              Assert.AreEqual("Name", a.ParamName);
  19:          }
  20:   
  21:          [Test]
  22:          public void Thrown_Throws_ExceptionNotThrownException_When_Exception_Not_Thrown()
  23:          {
  24:              TestClass t = new TestClass();
  25:              AssertExtensions.Thrown<ExceptionNotThrownException>(()=>
  26:                  AssertExtensions.Thrown<ArgumentNullException>(() => t.NoChuck()));
  27:          }
  28:      }
  29:   
  30:      public class TestClass
  31:      {
  32:          public void Chuck()
  33:          {
  34:              throw new ArgumentNullException("Name");
  35:          }
  36:   
  37:          public void NoChuck()
  38:          {
  39:   
  40:          }
  41:      }
  42:  }
Note the double use of the Thrown method in the second test. The inner most causes the ExceptionNotThrownException to be thrown and the outermost checks it was thrown.

I've used the ExceptionNotThrownException rather than a call to Assert.Fail as I'd like this to work in any testing framework.

Avoiding the mess of <% } %> in ASP.NET MVC

If you read Hadis' post on  ASP.NET MVCD you'll have noticed the rather unpleasant return to the bad old days of ASP code embedding in views. Even when we're following the MVC pattern closely you're still going to find a mess of C# syntax littering your beautifully crafted HTML. I don't there's much worse than having to open a script block just to finish a loop (the <% } %> alluded to in the title).

Fortunately the designers of the new MVC framework had the foresight to allow the use of different ViewEngines that allow HTML / code rendering in with far more pleasant syntax. Take, for example, Spark (my personal favourite). The entire ASP.NET rendering engine is ditched in Spark, and we're given a whole new syntax that melds control of rendering into your HTML seamlessly. Taking Hadis' original example of looping around a list we go from

   1:  <%foreach (Customer customer in ViewData.Model)
   2:  {%>
   3:      <tr>
   4:          <td style="width: 98px">
   5:              <%=Html.ActionLink(customer.Firstname, "Edit", new { id = customer.Id}) %>
   6:              &nbsp;
   7:          </td>
   8:          <td style="width: 112px">
   9:              <%=customer.Lastname %>
  10:              &nbsp;
  11:          </td>
  12:      </tr>
  13:  <% } %>

to

   1:  <for each="Customer customer in Customers">
   2:      <tr>
   3:          <td style="width: 98px">
   4:              ${Html.ActionLink(customer.Firstname, "Edit", new { id = customer.Id})}
   5:              &nbsp;
   6:          </td>
   7:          <td style="width: 112px">
   8:              ${customer.Lastname}
   9:              &nbsp;
  10:          </td>
  11:      </tr>    
  12:  </for>

There's a lot more to Spark than just this, conditional attributes on existing HTML elements (remember it goes through a whole different parser... they're doing some real magic under the hood), which enables statements like:

   1:  <p if='!user.IsLoggedIn()'>Login form</p>
   2:  <p elseif='user.HasRole(RoleType.Administrator)'>Hello - admin</p>
   3:  <p elseif='user.HasRole(RoleType.Registered)'>Hello - registered user</p>

or how about an each attribute on HTML elements so we don't need to use the <for/> element? Our updated HTML becomes:

   1:  <tr each="Customer customer in Customers">
   2:      <td style="width: 98px">
   3:          ${Html.ActionLink(customer.Firstname, "Edit", new { id = customer.Id})}
   4:          &nbsp;
   5:      </td>
   6:      <td style="width: 112px">
   7:          ${customer.Lastname}
   8:          &nbsp;
   9:      </td>
  10:  </tr>    

The one downside is that you'll lose the existing ASP.NET capabilities when it comes to master pages (they have their own version), user controls (they have something similar but not exactly the same) and built in ASP.NET controls. However, since we're coming at how we build our web applications from a different angle by using MVC, it's not necessarily a bad thing. It does mean that a lot of stuff that ASP.NET controls just did for us we need to relearn, however the state of Javascript extension packages has moved on considerably in the past few years (consider JQuery and their recent success in getting included in future release of ASP.NET).

If you're having a play with MVC give Spark a try, or one of the many other ViewEngines that are out there.

Subtext and friendly URLs

Which do you consider better as a URL for your blog post:

http://blogs.imeta.co.uk/dgray/archive/2008/10/01/409.aspx

or

http://blogs.imeta.co.uk/dgray/archive/2008/10/10/preventing-tfs-from-creating-work-items-when-a-build-fails.aspx

I know which I prefer, and I'm sure that search engines will give you a better ranking for the later. To set this up under Subtext (we're using version 1.9.5.177) simply go to the Options Tab, then under Preferences find the "Auto-Generate Friendly URL" checkbox. All future posts will come out with a much friendlier URL.

Preventing TFS from creating work items when a build fails

A review of work items today brought up hundreds of previously unnoticed work items for build failures. Our process doesn't currently handle this, so for the time being we've decided to simply disable the feature. Surprisingly a quick Google revealed nothing, so here's the very straightforward answer. Just add

<!-- SkipWorkItemCreation - Don't create a work item if the build fails -->
<SkipWorkItemCreation>true</SkipWorkItemCreation>

To your TFSBuild.proj file in one of the property groups and work item creation is surpressed - simple as just!

Testing with two frameworks - Why?

Just had an interesting conversation with a couple of colleagues about why I'm trying to get interoperability in my tests between MSTest and NUnit. I thought I'd covered this in an earlier post, but if not here's another summary.

The current implementation of MSTest inside of Visual Studio doesn't seem to fit (at least my interpretation of) how Test Driven Development should fit into your daily development cycle. Developing with unit tests needs to have a constant rhythm of code, test, code, test. Ideally the test part should be transparent, at least not seriously interrupting the flow of your coding. MSTest fails on this front as far as I'm concerned, things that are missing are:

  • When I rebuild my test assembly - rerun the last set of tests I ran
  • When you run my tests, do it out of the way - I don't want to know that you've run them until you find something that fails
  • If I've built my tests to run fast (as they should), I want you to run them fast

However, MSTest wins hands down over all other testing tools thanks to its' TFS integration. The publishing of results back into TFS and subsequent analysis in the datacube for results and code coverage is just superb.

This leaves me with a difficult problem - I want to use something like NUnit whilst coding, but also to use MSTest whilst building centrally. Hence why I'm trying to have my cake and eat it with the dual test framework idea.

I've not had the opportunity to use it on anything of any scale or importance yet, but I've confirmed the theory with a few simple projects I've got running in my home TFS Server. The NUnit GUI sits quietly in the background whilst I code, monitoring changes to the test assemblies, happily re-running the tests when its rebuilt, only making itself known when there's a failure. My TeamBuilds then switch over to running MSTest and I get the flow of data back into TFS that I was expecting.

As I get to use this pattern more often I'll keep you all updated on my progress (fingers crossed I can keep using it).

What do you listen to whilst developing?

I swear Hadi has some kind of blog post idea stealing telepathy power, that's the second time in 4 days he's pre-empted a post I was about to make with one of his own. I'd been prompted to write on the subject with my recent acquisition of a third monitor, the resurrection of a cheap PC I bought in Tesco for £150, Synergy, Media Monkey and a new 1TB Western Digital external drive. All of this has culminated in finally having my full music library with me at work (and not stealing MP3 decoding CPU cycles from my development machine), something which I'm really pleased about.

Like Hadi the music I listen to is split depending on the type of work I'm doing. For mechanical, heavy-coding sessions I'll listen to something that follows musically, so mainly Industrial bands like Skinny Puppy, KMFDM, Nine Inch Nails, :Wumpscut:, Angelspit or Razed in Black. If I'm working on design (especially anything with any layers of abstraction) then again the music follows this, Juno Reactor, Aphex Twin, Coil, Godspeed You Black Emperor!. If I'm writing something (blogs, training "bits", wikis, etc.) the music will tend to be quite wordy as well, Sneaker Pimps, Suede, Sugarcubes, Therapy?, Tori Amos.

Although the one overriding factor in all my music choices is the mood I'm in, music (for me at least) is a reflector and a director of emotion.

"If ever I would stop thinking about music and politics, I would tell you that music is the expression of emotion, whilst politics is merely the decoy of perception"

- Michael Franti, Music & Politics

Testing with two frameworks - what comes with one, doesn't come with the other

When I made my previous post about testing with two frameworks I'd inadvertently made a good decision to write the tests using the MS Test attributes on my classes, and then redirected them to the appropriate NUnit attributes, rather than the other way around.

Why was this a good decision? Because Microsoft have more attributes in common use than NUnit. Here's the comparative list:

MS Test Attribute NUnit Attribute Interoperable Purpose Other notes
TestClass TestFixture Yes Indicates that a class contains a number of tests to be run by the framework  
TestMethod Test Yes Indicates that a method is a test. Both frameworks expect the method to be public and with a void return.  
TestInitialize Setup Yes A setup method to be run before each test is run.  
TestCleanup Teardown Yes A teardown method used to clean up resources after each test is run.  
ClassInitialize TestFixtureSetup No - MSTest expects ClassInitialize to be static. A setup method to be run before ANY tests are run in a test class / fixture.  
ClassCleanup TestFixtureTeardown No - MSTest expects ClassCleanup to be static. A teardown method used to clean up resources after all tests in a test class / fixture is run. There's a further difference between the way the two frameworks handle these attributes. In NUnit the method is called immediately following the completion of the last test in a fixture, or after the Teardown method. In MSTest it is run before the AssemblyCleanup attribute (see this blog post).
ExpectedException ExpectedException Yes Instructs the framework that it is expected that the test will result in an exception being thrown.  
- Category n/a Defines a category for the test (see http://www.nunit.org/index.php?p=category&r=2.2)  
- Explicit n/a Requires the test be run explicitly (see http://www.nunit.org/index.php?p=explicit&r=2.2)  
- Suite n/a Defines a suite of tests  
Ignore Ignore Yes Indicates to the framework to ignore the test in all cases.  
AssemblyInitialize - n/a A setup method to be run before ANY tests are run in a test assembly.  
AssemblyCleanup - n/a A teardown method to be run after all tests are run in a test assembly.  
CssIteration - n/a Indicates the iteration in the project to which this test corresponds.  
CssProjectStructure - n/a Indicates the node in the team project hierarchy to which this test corresponds.  
DataSource - n/a Defines databinding for data driven testing  
DeploymentItem - n/a Indicates a file that MSTest must copy into the testing directory prior to running your test.  
Description - n/a Contains a description of the test.  
HostType - n/a Used to specify the type of host that this unit test will run in  
Owner - n/a Used to specify the person responsible for maintaining, running, and/or debugging the test.  
Priority - n/a Used to specify the priority of a unit test.  
TestProperty - n/a Generic test metadata container  
Timeout - n/a

Used to specify the time-out period of a unit test.

 
WorkItem - n/a Used to specify a work item associated with a test.  

That which doesn't hurt us...

The nice thing about the extra attributes found in MSTest is that we can either ignore them or circumvent them. For example DeploymentItem is only used by MSTest because of the way they move files into a test directory prior to running the tests, no such functionality is required in NUnit as it quite happily runs inside your binary output folders. The same can be said of all the meta data attributes (Owner, Priority, etc) which don't have a functional equivalent in NUnit, they're useful to decorate our tests inside Team System, but for our desktop testing they're largely irrelevant.

Unfortunately there's nothing we can do about the AssemblyInitialize, AssemblyCleanup, DataSource and HostType, if you're going down the dual testing framework route your going to simply have to not use them.

How to include a MSTest meta data attribute and not make NUnit hurl chunks

Quite straightforward really, we define ourselves a placeholder attribute that has constructors that match the signatures of the extra attributes and then redirect to this attribute in our using block.

 
   1:  namespace TestHelpers
   2:  {
   3:     [AttributeUsage(AttributeTargets.All)]
   4:     public class NullAttribute : Attribute
   5:     {
   6:        public NullAttribute(string v) { }
   7:     }
   8:  }

   1:  #if NUNIT   
   2:  using NUnit.Framework;
   3:  using TestClass = NUnit.Framework.TestFixtureAttribute;
   4:  using TestMethod = NUnit.Framework.TestAttribute;
   5:  using TestInitialize = NUnit.Framework.SetUpAttribute;
   6:  using TestCleanup = NUnit.Framework.TearDownAttribute;
   7:  using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
   8:  using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
   9:  using DeploymentItem = TestHelpers.NullAttribute;
  10:  #else
  11:  using Microsoft.VisualStudio.TestTools.UnitTesting;
  12:  #endif
  13:   
  14:  using System;
  15:  using System.Collections.Generic;
  16:  using System.Linq;
  17:  using System.Text;
  18:  using Library;
  19:   
  20:  namespace UnitTests
  21:  {
  22:     [TestClass]
  23:     public class TemperatureConverterTests
  24:     {
  25:        [TestMethod]
  26:        [DeploymentItem("ConversionChart.xml")]
  27:        public void FahrenheitToCelsius_0Degress_Fahrenheit()
  28:        {
  29:           Assert.AreEqual(-18d,Math.Round(_converter.FahrenheitToCelsius(0),0));
  30:        }
  31:     }
  32:  }

Lather, rinse, repeat the "using DeploymentItem = TestHelpers.NullAttribute;" for all the additional attributes you're using and everything should compile, and NUnit will happily ignore the strange attributes it knows absolutely nothing about.

Final safety tip

Put your conditional using block at the TOP of your list of usings. Doing this prevents the IDE from inserting new usings (inserted using resolve) into the part of the IF block you're currently using. It can get very confusing trying to figure out why your tests don't compile in release, but do in debug.