What is White Box BDD ?
White Box BDD is built around the concept of writing meaningful Unit tests. With White Box Behaviour Driven Development sometimes referred to as SDD or Specification Driven Development we are trying to provide a behaviour statement around an object or a tree of objects which supply a given set of functionality.
White Box BDD attempts to provide a way to describe the behaviour within a system unlike black box BDD which classically attempts describe a behaviour of a whole vertical slice of a system.
The tools we are using
My own development setup is as follows:
· Visual Studio 2012 http://www.microsoft.com/visualstudio/11/en-us
· Resharper 7 http://www.jetbrains.com/resharper/whatsnew/index.html
· NUnit http://nuget.org/packages/nunit
· NUnit Fluent Extensions http://fluentassertions.codeplex.com/
I find the above combination of software packages to be absolutely stunning as a development environment and Windows 8 is absolutely the most productive Operating System I have ever used across any hardware stack, as always without Jet Brains Resharper Visual studio feels almost crippled. NUnit is my go to testing framework but of course you have MBUnit, XUnit and for those who must stick with a pure Microsoft ALM style experience you have MSTest. Overlaying a Fluent extensions library allows me to write more fluent and semantic assertions which falls in line with the concepts of White Box BDD. For most of the frameworks above there are similar sets of extensions available, MSTest is to my knowledge the exception to the rule.
The http://fluentassertions.codeplex.com/ framework is particularly powerful as this allows you to chain assertions as shown by some of the examples taken from their site below.
var recipe = new RecipeBuilder()
.With(new IngredientBuilder().For(“Milk”).WithQuantity(200, Unit.Milliliters))
Action action = () => recipe.AddIngredient(“Milk”, 100, Unit.Spoon);
.WithMessage(“change the unit of an existing ingredient”, ComparisonMode.Substring)
string actual = “ABCDEFGHI”;
There are other choices and the techniques contained in this article can be used with earlier versions of the Microsoft development environments and indeed in most modern languages you can find tooling support including but not limited to:
· Java – Intilij, Eclipse + JUnit
· Ruby On Rails – Ruby Mine
In fact the techniques can be universally applied to any modern development environment and I am yet to come across a project that cannot be tested where it has been correctly conceptualized and developed in line with SOLID http://en.wikipedia.org/wiki/Solid_(object-oriented_design) principals.
Let’s look at some code
Step 1 – Add a Specification Project
First step is to create a specification library because we are going to use our specifications to drive our package and project choices we do not start with a production code project such as an ASP MVC project but instead we only need at this stage add our specification library.
This introduces an important principal which drives White Box BDD called Emergent Design this principal says that the natural act of coding will force the correct design for the application to emerge and therefore design upfront with the exception of big block conceptualization is invalid and in fact we should allow our architecture to naturally emerge.
Looking at the image above you can see that we have used the .Specifications extension to the project name which will naturally be reflected in the project namespace, this is my personal preference and for me implies the intent of the project.
Step 2 – Write Test based on your requirements
For the scope of this demonstration I am going to keep the requirements very simple I will outline them below using Gerkin’esk style syntax.
Given that I have a set of text
When I pass the text into the Encoder
Then I expect to be given back a correctly encoded base 64 fragment of text
Next we add the packages via Nuget
The next step is to add the acceptance criteria. It is crucial that this is the first step we start with
What you will notice is that Resharper has marked the things it doesn’t know about in RED. We now follow the RED clicking on the RED and using Resharper’s Alt+Enter command helps us to do this.
While I was getting the expectedEncodedText from an online base 64 encoder site I released that Encode() needed a parameter passing in for the source Text so let’s add this. It’s worth noting we didn’t forget about this but rather we waited till we were driven to implement it. This Is fundamental to this style of coding.
Next we run the test and we see that we are RED and we hit The NotImplementedException
Step 2 – Make the Test Go Green
The next step we need to make the test pass or go green this will give to us a guarantee of the behaviour or specification as expressed by the assertion.
First of all I add the base64 encoding code
Lets run the test again.
We now find that we are Green.
This is a rather trivial example but what have we done here in easy to understand points:
· One we described a behaviour or rather a specification for a behaviour using the test name and the Assert.
· Two we drove out the code directly from the Test using Resharper Magic.
· Three our end point was a passing specification.
I hope this example has been useful if basic.