BDD stands for Behaviour Driven Development and is a term coined by Dan North. The story goes that Dan was running a TDD workshop, and noticed that the participants were getting distracted by the junit syntax, so he started expressing tests in terms of Given, When and Then steps.
Given 100 bottles of beer are sitting a the wallThis led him to write jbehave, a tool for mapping ordinary language steps to executable functions. Since then a host of other BDD tools such as Cucumber, RSpec, Concoordian, Specflow and Twist have sprung up.
When 1 falls
Then there should be 99 bottles of beer
There has been some argument that BDD is not a real thing, that it's just TDD done well. The counter argument is that the difference is the audience. If your tests are written in code, then the audience are developers. If your tests are written in an ordinary language, your audience can be anybody. I've been writing BDD tests for about five years now, but I've only once found a non developer with enough time, patience and discipline to co-author BDD tests. It was the most effective project I've ever worked on. So I think there is a difference, but it's rare that you'll be in a position to capitalise on it.
The BDD Sweet SpotHowever, there is another compelling reason for using BDD tools. They soothe the pain of functional testing. Web testing especially. When you write web tests you are likely to encounter the following problems...
- The tests take a long time to write. This is due to what Rob Fletcher calls cadence. The cadence for functional tests will be higher than unit tests because the tests run much more slowly. Things quickly get much worse if you have to rebuild / restart your application whenever you change production or test code. It's usually hard to debug / step through functional tests too.
- The test suite takes a long time to run. Sometimes so long it's only run at night. This means the tests are usually broken in the morning and it's some poor souls job to fix all the problems that were introduced the day before. After a while the team gives up on writing functional tests.
- The tests are incomprehensible. They contain xpath expressions like '//table/tr/td' or css expressions like 'table#report tr.data td.total span'. Because the test data takes so long to set up, developers keep appending tests to each other.
- The tests are brittle. Any time you change your page markup you're likely to break numerous tests. This can limit peoples enthusiasm for refactoring HTML and CSS.
- The tests all break at once. Because most functional test tools don't provide an abstraction layer, and because often developers think of writing one until too late, and because of a "it's only test code" mentality, and because when testing is done last it's seen as a chore, it's common for those brittle xpath expressions to be copy and pasted like no tomorrow.
Since true BDD tools are written in an ordinary language, not only are they (hopefully) comprehensible - solving problem #3, but they also provide an effective abstraction layer, solving problem #5 and thereby greatly reducing the impact of problem #4. Once you've built up a respectable library of test steps, your abstraction layer will enable a high degree of reuse and you'll also partially mitigate problem #1.
The only true BDD tool I found during my search was CucumberJS. The problem with CucumberJS is that the Gerkin syntax is restrictive. I don't want to be limited to starting my sentences with Given, When, Then, And and But. I want to express myself naturally. I also want a test runner makes good decisions about which steps to run, instead of picking the first matching one it comes to. I want a tool that doesn't fail silently. I want a tool that I can use synchronously or asynchronously. I want a tool that lets me plugin different step libraries so that I can test multiple interfaces (e.g. rest and HTML) with the same scenarios. I even want a tool that has nothing to do with testing and just maps ordinary sentences to functions so I could use it in a rules engine or build script. That's why I wrote Yadda.