Following on from my previous post I thought it only fair to dive down into the code that was shown in that article and give a bit more of an explanation on what is going on.
First of all, some of you may have looked at the sample code and asked “What is the ContextSpecification class that the ShoppingCartContext is derived from?” – fair question and one that deserves to be explained.
Allow me to digress momentarily in order to try and set the context (for you seasoned BDD’rs – pun intended!). I was first introduced to BDD (indirectly) at a session on coding Katas at TechEd 2010 in New Orleans and BDD was not exactly why I had attended the session. The Behavior Driven aspect of the interactive presentation was very brief and at the time I was left with the desire to know more, so before the End of TechEd party I spent time scouring numerous technical and not so technical sites – looking for further details. What I found was far more than I had bargained for; it wasn’t that the tests were written in a natural language sort of way, it was the idea that the code was being driven via tests that were in turn driven by use cases – OMG!!!! You mean that the requirements analyst directly affects the way the tests are written? I had already bought in to the TDD mindset and to me it had made perfect sense, but this was far beyond what I had bargained for. So in true engineering fashion – I tried it out myself and low and behold it worked (albeit in a very sanitized and benign sort of way). Before we go any further, I would highly recommend that you read Dan North’s Introduction to BDD (http://behaviour-driven.org/Introduction); there you will see that many of us may be fortunate to get to step 4 of the steps to enlightenment. In my case I was there and thanks to the intro to BDD I would get to 6 and hopefully on to step 7.
So there I am trying to implement my first set of BDD tests (before code implementation) and I hit my first stumbling block. The Context Specification Framework I had been introduced to at TechEd, Machine.Specification by Aaron Jensen (http://github.com/machine/machine.specifications), had wonderful plugin capabilities for ReSharper but nothing that I could use inside of MSTest; yes I know, “big deal”, “so what”, blah, blah… Well as much as I love ReSharper, I still prefer to run MSTest as it is what is run in my build environments. Therefore anything that I have difficulty running with MSTest will be an even bigger hassle on my build machines. So off I went again, looking for more jewels in the proverbial rain-forest of information and lo-and-behold I came across Eric Lee’s implementation of a base class that uses MSpec (http://blogs.msdn.com/b/elee/archive/2009/01/20/bdd-with-mstest.aspx) called ContextSpecification. It is a superb abstract class that allows me to easily write my BDD style test classes and thereby drive my code implementation.
Now then, we have the MSpec assembly reference and now an abstract class (ContextSpecification) to derive from and as I am a big fan of RhinoMocks (for generating mocks or stubs), let’s throw that into the mix. With this base we are ready to go do some BDD.
As I have stated before, the Requirements are what drive our tests in BDD; more specifically the creation of Use Cases will drive the tests. So going back to the example in my previous post, we will start with the following requirement:
A customer can add items to their shopping cart.
Strictly speaking, in SCRUM terms, this should be written as follows:
AS A Customer
I WANT to be able to add items to a shopping cart
SO THAT I can keep a collection of items that I want to buy.
From this user story we can expand the Use Cases (I also consider them as Conditions of Acceptance for the User Story) to give me detail to the high level statement:
Scenario 1: Adding items to an empty shopping cart
- GIVEN that the shopping cart is empty
- WHEN the customer adds 1 item
- THEN the shopping cart should contain 1 item
Scenario 2: Adding items to a full shopping cart
- GIVEN that the shopping cart contains 2 items
- WHEN the customer adds 1 item
- THEN the shopping cart should contain the 2 existing items and the 1 new item.
I have purposefully capitalized the GIVEN, WHEN and THEN, simply to draw parallels with the AS A <role> I WANT <functionality> SO THAT <benefit> of SCRUM and hopefully highlight the fact that patterns can be drawn from both and thereby help us to create consistent ways in which to write both User Stories and Use Cases.
Now that we have our Use Cases we can start to create our tests. Taking the first scenario we will need to setup a Shopping cart context; which is where we bring in the ContextSpecification abstract class (remember, we don’t have any implementation code yet):
namespace Bdd.Shopping
{
public class ShoppingCartContext : ContextSpecification
{
/// <summary>
/// The "Given some initial context" method
/// </summary>
protected override void Context()
{
// setup your class under test
}
}
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1 : ShoppingCartContext
{
/// <summary>
/// The "When an event occurs" method
/// </summary>
protected override void BecauseOf()
{
//
// TODO: Add behavior setup (Action) here
//
}
/// <summary>
/// The "then ensure some outcome" method.
/// </summary>
[TestMethod]
public void TestMethod1()
{
//
// TODO: Add test logic here
//
}
}
}
Remember that the use case was written as follows:
- GIVEN that the shopping cart is empty
- WHEN the customer adds 1 item
- THEN the shopping cart should contain 1 item
The “GIVEN” aspect of the use case is the Context() method of our base class – where we initialize our member variables.
The “WHEN” of the use case will be the TestClass – this will be the container for the THEN aspect.
The “THEN” will be the TestMethod and perform the appropriate assert(s).
Putting all of this together we arrive at the following:
namespace Bdd.Shopping
{
public class ShoppingCartContext : ContextSpecification
{
protected ShoppingCart _cart;
}
/// <summary>
/// Test Class for "WHEN the customer adds 1 item THEN the shopping cart should contain 1 item"
/// use case.
/// </summary>
[TestClass]
public class when_1_item_is_added_to_an_empty_shopping_cart : ShoppingCartContext
{
/// <summary>
/// The "Given some initial context" method
/// </summary>
protected override void Context()
{
_cart = new ShoppingCart();
}
/// <summary>
/// The "When an event occurs" method
/// </summary>
protected override void BecauseOf()
{
ShoppingItem item = new ShoppingItem();
_cart.Add(item);
}
/// <summary>
/// The "then ensure some outcome" method.
/// </summary>
[TestMethod]
public void then_the_shopping_cart_should_contain_1_item()
{
Assert.AreEqual(1, _cart.Items.Count);
}
}
}
The class name of the TestClass and the method name of the TestMethod help us associate the test with the first use case; “WHEN the customer adds 1 item THEN the shopping cart should contain 1 item”.
In true TDD fashion we have only implemented enough to compile (i.e. absolute minimum of implementation classes) – so this test will fail:

The next step, of course is to put in the functionality to get the test to pass (TDD mantra – Red, Green, Refactor, Repeat until all test are done). In the case of the implementation classes, we will go from this:
public class ShoppingCart
{
internal void Add(ShoppingItem item)
{
throw new NotImplementedException();
}
public List<ShoppingItem> Items { get; set; }
}
public class ShoppingItem
{
public ShoppingItem() {}
}
To this:
public class ShoppingCart
{
public ShoppingCart()
{
Items = new List<ShoppingItem>();
}
internal void Add(ShoppingItem item)
{
Items.Add(item);
}
public List<ShoppingItem> Items { get; set; }
}
public class ShoppingItem
{
public ShoppingItem() {}
}
This will give us green in our first test:

Now we move on to the next use case:
- GIVEN that the shopping cart contains 2 items
- WHEN the customer adds 1 item
- THEN the shopping cart should contain the 2 existing items and the 1 new item.
Here we see that the Use Case is more specific in that it is requiring us to check that the latest item has been added – we will need to add an identifier to the item be able to check against it in our assertion. This will mean that we will need to run our first test again as we will be changing the implementation classes.
First we write the new Test class and associated Test method and do the minimum implementation to get it to compile.
New Test class and Test method:
[TestClass]
public class when_1_item_is_added_to_a_cart_containing_2_items : ShoppingCartContext
{
private const string NewItemTitle = "Test Driven Development By Kent Beck";
/// <summary>
/// The "Given some initial context" method
/// </summary>
protected override void Context()
{
_cart = new ShoppingCart();
ShoppingItem item = new ShoppingItem("Behavior Driven Development By Dan North");
_cart.Add(item);
item = new ShoppingItem("Agile Software Development with Scrum By Ken Schwaber and Mike Beedle");
_cart.Add(item);
}
/// <summary>
/// The "When an event occurs" method
/// </summary>
protected override void BecauseOf()
{
ShoppingItem item = new ShoppingItem(NewItemTitle);
_cart.Add(item);
}
/// <summary>
/// The "then ensure some outcome" method.
/// </summary>
[TestMethod]
public void then_the_shopping_cart_should_contain_the_2_existing_items_and_the_1_new_item()
{
Assert.AreEqual(3, _cart.Items.Count);
Assert.AreEqual(NewItemTitle, _cart.Items[2].Title);
}
}
Minimum implementation classes:
public class ShoppingCart
{
public ShoppingCart()
{
Items = new List<ShoppingItem>();
}
internal void Add(ShoppingItem item)
{
Items.Add(item);
}
public List<ShoppingItem> Items { get; set; }
}
public class ShoppingItem
{
public ShoppingItem(string title) {}
public string Title { get; set; }
}
When we run the test, the first one will still pass, but seeing as we have done the minimum to be able to compile the second test will fail:

So therefore the next stage is to make the red go green and “back fill” the correct functionality – to update the implementation class as follows:
public class ShoppingItem
{
public ShoppingItem(string title)
{
Title = title;
}
public string Title { get; set; }
}
Now when we run the tests all should be green:

As we continue we are always aligning our code with the use cases and therefore ensuring that we are adding the business value as intended. With the TDD aspect we are also ensuring that any changes we do to the implementation can be done so with the peace of mind that as long as all of the tests past before we go on to the next use case, we will be building robust code.
As I have said in this blog post and the previous one, BDD is a natural evolution of TDD in as much that it adds the linkage from the tests to the requirements. At a personal level it is also a natural progression in my continuous evolution as a software professional and it helps to consolidate my understanding of the requirements more than any type of review ever could.
Make no mistake, BDD and (especially) TDD are a definite shift in mindset mostly in the idea that the test is written first and you only write enough of the implementation to be able to get the test to pass. This puts the onus on the test being right in the first instance and places more significance on the testing aspect of software development.

























