The advantage of using BDD over TDD
Introduction
After reading the latest post from @jeremydmiller I felt the urge to write a small article about the BDD part since there might be missing a vital part here about BDD...
What is true BDD ?
For a general introduction on BDD I would like to refer you to wikipedia. There are also a lot of articles on this blog on specific issues as well.
Just to get an idea I'll show you an excerpt of a spec (taken from here):
Define a browser
using Be.Corebvba.Aubergine.Examples.Website.Contexts.BrowserContext
from Be.Corebvba.Aubergine.Examples.DLL
Story Make sure my website gets enough visibility
Is about a browser
As a website owner
I want to make sure that I get enough visibility
So that I can get enough traffic
Scenario Search results for 'keywords' on searchengine should contain 'www.corebvba.be'
Given the current url is 'search url'
When searching for 'keywords'
Then the result should contain 'www.corebvba.be'
Example
+--------------+--------------------------------+------------------+
| searchengine | search url | keywords |
+--------------+--------------------------------+------------------+
| google | http://www.google.be/search?q= | BDD .Net |
| bing | https://www.bing.com/search?q= | core bvba tom |
| bing | https://www.bing.com/search?q= | Quantum physics |
| faulty link | https://www.googleaaa | core bvba tom |
+--------------+--------------------------------+------------------+
Scenario Search results on google for keywords should contain 'www.corebvba.be'
Given the current url is 'https://www.google.be/search?q='
When searching for the following keywords
+-----------+
| keywords |
+-----------+
| Aubergine |
| BDD |
+-----------+
Then the result should contain 'www.corebvba.be' and the following markup elements
+------------------+
| type | inner |
+------------------+
| em | BDD |
| em | Aubergine |
+------------------+
Each time I compile my application, these specs get executed, and I get a report about which specs fail and which specs succeed, so you customer knows which functionalities are working.
In a true bdd engine specs are written using an intermediate language (a.k.a. ubiquitous language).
The biggest advantage of this extra layer is that it makes your specs completely independent from your design/infrastructure implementation.
This also implies that I personally do not consider engines that require writing your specs in code (like @aaronjensen's mspec for example) as true BDD engines. (Please do note that this is my personal opinion)
Why is that an advantage ?
The first advantage is that this domain language is usable/understandable by domain experts as well. All you have to do is send them a link to the latest build bdd html report, and they know what to expect from your app...
Given you explain the available grammar for a context to a domain expert he/she should even be able to write their own scenario's. (Hence, my bdd engine has a commandline option to get the available grammar from a context DLL, so in theory you could send the compiled DLL to the domain expert and let him/her write the specs)
The second one is a bit less obvious, and is why one requires the ubiqutous langugage in a true BDD engine: since behaviour almost never changes, you can simply replace complete parts of an application without having to rewrite your specs. Instead of fixing tests you only need to fix your contexts.
You never have to rewrite your specs, since the bevaviour does not change, it's only the implementation that does
Fixing context implementations is a usually less work compared to rewriting tests since a test usually contains some/a lot of dependencies in comparision to a single sentence of context grammar (which typically handles only a single dependency).
As an example I am giving this anology : if behavioural tests would be an app written using an ioc container and dependency injection principles, then unit tests would be an app written without them.
If you apply bdd-like practices to tdd (also known as Arrange/Act/Assert) you are missing out on a large part of BDD imho; it is like writing your apps using dependency injection, but without using a container: it works and it makes your code better, but you could make your life a lot easier if you would use a container.
Another advantage: refactoring
Another huge advantage that I initially missed in my reflections on BDD, is even more important:
By defining your behaviour before writing a single line of code, both you and the domain experts can think your app through upfront, and refactor at will
Think about this a little bit. Usually you have a certain idea about how an app is supposed to behave. Your customer has this idea as well, but the problem might be that the customer's ideas are different from your's.
Bij defining the behavior of the app explicitly in BDD specs, you rule out a lot of the (rather frustrating) refactorings due to misinterpretations, since the possible mismatch between different interpretations is closer to zero.
A few months ago, I have been refactoring a BDD story over and over during a whole week together with a domain expert, and the end result was that we managed to switch from umphteen screens to only 3; this was a huge win, since we did not only have less UI to implement, but the whole process became a lot simpler for the user !!!
Finally
Whether you *do* start using BDD is completely up to you. As you might know, there is no silver bullet, but it might be a tool that helps a little.
In my personal experiences opinion BDD is currently the way to go; but I might be a bit opinionated, since I have been dogfooding my own BDD engine for a few months now...
And for those of you why think I am suffering from the "Not-invented-here"-syndrome, you are probably right - although I have written an Aubergine manifest to explain why we needed another bdd engine- .
Happy development !!