Posted: Thursday 15th July 2010
A number of tools for Behaviour Driven Development (BDD) have emerged from the open-source community, mostly targeting Ruby On Rails or Java, but a number have been written to target .NET. All of them take a slightly different approach, some have new ideas and some are direct ports from other language implementations. What options are out there for .NET?
BDD is a fairly young agile methodology that has evolved from Test Driven Development (TDD) as a way to develop software with more emphisis on the business benefits than the technical implementation. The key benefit is that BDD allows a development team to have a clearer understanding of the software behaviour the stakeholders require by using a common language that non-programmers can read (and write). This language is what forms BDD tests with the tools linking the language to the code that actually peforms the Arrange, Act & Assert (AAA) actions.
The Tooling
I investigated a number of tools out in the community and seem to find a new one almost weekly, but decided to narrow down the list to a few popular ones that implement the Gherkin language. Gherkin has been made popular by the tool Cucumber for Ruby On Rails and I like the syntax because it is well structured yet reads nicely for the stakeholder without showing any technical detail. In contrast, other BDD tools such as NSpec (a port of RSpec for Ruby) are more technically oriented and seem to suit lower-level unit testing, which a stakeholder should not be concerned with. The couple I've looked at in any depth are StoryQ and SpecFlow, although there are others such as Cuke4Nuke, Spector, MSpec, NBehave and even Cucumber can be run against .NET code (using Ruby).
The example below shows a test feature written in the Gherkin language for deleting folders within Contensis, which I will use to show the approach differences of each tool.
Feature: Manage Folders
In order to organise my website
As a Content Editor
I want to be able to manage folders
Scenario: Delete Folder
Given I have the folder to delete
And I have permission to delete content
When I try to delete the folder
Then the folder should no longer be a child of the parent folder
StoryQ
StoryQ was actually the first one I got to play with and liked straight away because of it's simplicity to get started. The general design is a framework that executes within normal NUnit tests and using a Fluent style API you can build your scenarios purely in code. The download comes with a little WPF converter app that allows you to paste in your feature text (with basic intellisense) and will generate the code for you, allowing you to target either NUnit or the Microsoft Test Framework. The result looks something like this which you would paste into visual studio:
[Test]
public void ManageFolders()
{
new Story("Manage Folders")
.InOrderTo("organise my website")
.AsA("Content Editor")
.IWant("to be able to manage folder")
.WithScenario("Delete Folder")
.Given(IHaveTheFolderToDelete)
.And(IHavePermissionToDeleteContent)
.When(ITryToDeleteTheFolder)
.And(TheFolderShouldNoLongerBeAChildOfTheParentFolder)
.Execute();
}
private void IHaveTheFolderToDelete()
{
throw new NotImplementedException();
}
private void IHavePermissionToDeleteContent()
{
throw new NotImplementedException();
}
private void ITryToDeleteTheFolder()
{
throw new NotImplementedException();
}
private void TheFolderShouldNoLongerBeAChildOfTheParentFolder()
{
throw new NotImplementedException();
}
To me it looks very clear, all you have to do is reference the StoryQ dll, implement the generated methods and your test will run, but my niggling problem with it is the need for the converter tool to turn the requirements from the stakeholder into something that executes. The positive I can see from this though is that we can use the in-built Visual Studio refactoring capabilities to change whatever we want, but what if the stakeholder wants to change something ?!?
SpecFlow
The specflow.org website is well presented and provides nice guidelines. To use SpecFlow, you are required to install a plug-in for Visual Studio integration, which when I read it almost made me discount it completely. A new content type of .feature file is available which is where you put your feature text. On the saving of that file, the plug-in works its magic and generates the code that will execute your tests, which thankfully is code that you should not ever have to look at. In true BDD style, running the tests at this point fails with a console output specifying that step implementations need to be added to a step class (a class decorated with a Binding attribute), which is simply a cut and paste exercise. Running the tests again result in inconclusive test results, leaving you to fill in the implementations to make the tests pass. The execution engine uses NUnit again, but this time as a set of NUnit extension attributes, as the example below shows:
[Binding]
public class DeleteFolderSteps
{
private Folder toDeleteFolder;
private Folder manageFoldersFolder;
[Given(@"I have the folder to delete")]
public void GivenIHaveTheFolderToDelete()
{
toDeleteFolder = FolderFactory.GetFolder(49849, 1);
}
[Given(@"I have permission to delete content")]
public void GivenIHavePermissionToDeleteContent()
{
// Code to check permissions for the user
}
[When(@"I try to delete the folder")]
public void WhenITryToDeleteTheFolder()
{
toDeleteFolder.Delete(true);
}
[Then(@"the folder should no longer be a child of the parent folder")]
public void TheFolderShouldNoLongerBeAChildOfTheParentFolder()
{
Assert.That(manageFoldersFolder.ChildFolders.Contains("ToDelete"), Is.False);
}
}
Again, I think the code is really readable, with the notable difference between this and StoryQ being that the feature (Gherkin) is in a separate file which can be changed independently from it's code implementation. Running these tests requires NUnit and a reference to TechTalk.SpecFlow.dll.
Conclusion
Overall I've been mostly impressed by SpecFlow, but that's not to say I won't try another tool and like that better. Both StoryQ and SpecFlow are based on Gherkin which makes them accessible for developers or even stakeholders who have prior experience on other projects that may have used a Gherkin based BDD testing framework. Both tools produce pretty-print test result reports and both integrate well into existing Continuous Integration test runners without much faff.