Tuesday, March 5, 2013

Nooks & Crannies

Today I used two features in NUnit that I have never used before and I thought I would share for those who have yet to discover these great features as well.


TestFixture Parameters

Did you know that the TestFixtureAttribute can take parameters?

   1:  [TestFixture("My Name")]

Did you know that you can place more than one on your class?

   1:  [TestFixture("My Name")]
   2:  [TestFixture("Your Name")]
   3:  public class SimpleTests
   4:  {
   5:  }

I have recently been writing normal NUnit tests in a BDD influenced style. I know there are frameworks like SpecFlow and machine.specifications that are better then what I am doing, but at work I am trying to reduce the number of frameworks I introduce in a week, and those two are pretty invasive in that they both require VS2102 integrations for their maximum benefit.

For my BDD-ish test I have taken to making test fixtures that look like this

   1:  [TestFixture]
   2:  public class SimpleGreeterTests
   3:  {
   4:      [SetUp]
   5:      public void SetUp()
   6:      {
   7:          EstablishContext();
   8:          given_I_have_a_name();
   9:          when_the_greeter_greets();
  10:      }
  11:   
  12:      [Test]
  13:      public void then_the_greeting_should_say_hello()
  14:      {
  15:          Assert.That(Result, Is.EqualTo(string.Format("Hello {0}", Name)));
  16:      }
  17:   
  18:      protected string Name { get; set; }
  19:      protected IGreeter Subject { get; set; }
  20:      protected string Result { get; set; }
  21:   
  22:      protected void EstablishContext()
  23:      {
  24:          Subject = new Greeter();
  25:      }
  26:   
  27:      protected void given_I_have_a_name()
  28:      {
  29:          Name = RandomDataHelper.Get<string>();
  30:      }
  31:   
  32:      protected void when_the_greeter_greets()
  33:      {
  34:          Result = Subject.Greet(Name);
  35:      }
  36:  }

This pattern is something I am really enjoying and not the real topic here.

Today I created a test very similar in nature to this. I my case I need to code to return something different based on specific values of name. I thought I would have to write multiple suites. I knew I could execute a test multiple times with the TestCase attribute, but with this BDD structure to my tests, I needed the data to vary within the scope of the SetUp method.

Luckily NUnit introduced TestFixture parameters in 2.5. Which allowed me to make a test like this

   1:  [TestFixture("Jimmy", "Hello Mr. Bosse")]
   2:  [TestFixture("Lisa", "Hello Mrs. Bosse")]
   3:  public class SimpleGreeterTests
   4:  {
   5:      [SetUp]
   6:      public void SetUp()
   7:      {
   8:          EstablishContext();
   9:          given_my_name_is(_name);
  10:          when_the_greeter_greets();
  11:      }
  12:   
  13:      [Test]
  14:      public void then_the_greeting_should_say_hello()
  15:      {
  16:          Assert.That(Result, Is.EqualTo(_greeting));
  17:      }
  18:   
  19:      protected string Name { get; set; }
  20:      protected IGreeter Subject { get; set; }
  21:      protected string Result { get; set; }
  22:   
  23:      public SimpleGreeterTests(string name, string greeting)
  24:      {
  25:          _name = name;
  26:          _greeting = greeting;
  27:      }
  28:   
  29:      protected void EstablishContext()
  30:      {
  31:          Subject = new Greeter();
  32:      }
  33:   
  34:      protected void given_I_have_a_name(string name)
  35:      {
  36:          Name = name;
  37:      }
  38:   
  39:      protected void when_the_greeter_greets()
  40:      {
  41:          Result = Subject.Greet(Name);
  42:      }
  43:  }

CollectionAssert.Order

The next little gem I discovered was the more robust asserts NUnit lets you do against collections. For years I have been testing that my arrays contain the same elements

Assert.That(thisArray, Is.EquivalentTo(thatArray));

but today I needed to make sure my array was in the correct order. Through the magic of intellisense I was able to find this little nugget

Assert.That(thisArray, Is.Ordered.By("LastName"));

Lesson Learned

While my approach to new frameworks is often to find out just enough to get me going on the thing I  am building right now, I think I will try harder to fight TL;DR; and spend more time in the nooks and crannies.

No comments:

Post a Comment

Follow me on App.net