NUnit Behavior Driven Development


I know it has been a while since I posted but I have been working on several projects lately one of which involves Behavior Driven Development.

I am enamored about the concept with BDD. I strongly believe it is a natural evolution of the TDD movement.  Having practiced TDD over the last 3 years there have been many times where I have questioned how to test a certain component.  The reason is as a developer I am focused on the Test and not the why.  BDD’s expressiveness allows me to elucidate the why.

Having had several conversations about BDD with of my colleagues, the misconception is that you simply replace [TestFixture] attribute with [Context] and replace all the [Test] attributes with [Spec].  This cannot be further from the truth.

The key concepts we must focus on are “context” and “expressive test names”.  Just as Eric Evans gave us the concept of modeling an object model using a ubiquitous language based on the business domain.  We as developers must focus on the contextual expression of the behavior of our object model as  it relates to the business domain.

At work I have begun to incorporate Dan North’s concept of the (Given, When, Then) template structures for acceptance test.  So far there has been some hesitation on fully adopting these concepts.  I believe it is more of a cultural constraint than anything else but like all change, you should always expect some resistance.  Let’s examine the (Given, When, Then) constructs.  I am taking the scenarios from the RSpec tutorials so the concepts can flow easier.

 

Given some initial context (the givens),

When and even occurs (the why),

Then ensure some outcome (the test)

 

Example:

Given A new stack

When the new stack is created

Then it should be empty

 

Now I strongly believe in reuse and having used NUnit over that pass 2 years and having invested in over 4200 units test in our architecture, I was not about to start using a new framework just for BDD.  Oh what do…  Luckily NUnit is extensible.  Through the magic of the NUnit.Core.Extensions namespace I was able to incorporate my own attributes of “Context” and “Spec” into the test runner. Sweet!!!!  This allowed me to utilize my entire TDD test suite and start using BDD.  Not to mention I didn’t have to do anything with NAnt or CruiseControl.

So I came up with the following test.


namespace Domain.Tests.Stack


{


    [Context]


    public class ANewStack


    {


        private Stack<int> stack;


 


        [SetUp]


        public void SetUp()


        {


            stack = new Stack<int>();


        }


 


        [Spec]


        public void ShouldBeEmpty()


        {


            Assert.IsEmpty(stack, ” is not empty”);


        }


    }


}


</SPAN></SPAN>


Lets talk about the above code.  Lets talk old school, Red, Green, Refactor.  The concepts still apply but for the sake of this post I am already in the green state so you missed the most important part of the BDD experience.   Remember I mentioned earlier about “expressive test names”, well when the test first failed this was the error message in the Test Runner.


 


Domain.Tests.Stack.ANewStack.ShouldBeEmpty: is not empty


 


This error message conveys several key concepts.


1.       We are dealing with the Stack object


2.       The context is a new stack


3.       Since it is a new stack is should be empty


4.       But it’s not.


So at this point I created the stack and made the test pass.


Here is my proposal in using NUnit and BDD.


·         Utilize the Namespace to categorize the domain entities


·         The class names should convey the context of the specification you are asserting.


·         The method name should convey the specification you are asserting.


·         If possible use the NUnit.Core.Extensions.BDD to decorate the class structure with “Context” and “Spec” attributes.


Below is the final state of the test suite using BDD.


using System;


using System.Collections.Generic;


using NUnit.Core.Extensions;


using NUnit.Framework;


using NUnit.Framework.Extensions;


 


namespace Domain.Tests.Stack


{


    [Context]


    public class ANewStack


    {


        private Stack<int> stack;


 


        [SetUp]


        public void SetUp()


        {


            stack = new Stack<int>();


        }


 


        [Spec]


        public void ShouldBeEmpty()


        {


            Assert.IsEmpty(stack, ” is not empty”);


        }


 


 


        [Spec]


        public void ShouldNotBeEmptyAfterPush()


        {


            stack.Push(1);


           


            Assert.IsNotEmpty(stack,” is empty”);


        }


 


    }


 


    [Context]


    public class AStackWithOneItem


    {


        private Stack<int> stack;


 


        [SetUp]


        public void SetUp()


        {


            stack = new Stack<int>();


        }


 


        [Spec]


        public void ShouldReturnTopWhenYouPop()


        {


            stack.Push(1);


            Assert.AreEqual(1, stack.Pop(), “error when popping”);


        }


    }


 


   


}


To push the envelope even further once the .Net 3.5 framework is released it makes perfect sense to incorporate the extensions that Scott Bellware has created for BDD.


 


I plan to make the NUnit BDD extensions available I am just tweaking them before I host them on Google.



 

</SPAN></p>

Agile Project Management Reading List