The logical starting point would be to define what Behavior Driven Development is, but it’s difficult to jump right out and explain exactly what it is, until you first explain what it is not. To do that, I’ll have to digress a bit, and discuss Test Driven Development.
Some of you who read this will likely already have a good grasp of what Test Driven Development is, so you can skip on to the next section. However, for those who, like me, put the cart before the horse on a regular basis, read on.
Test Driven Development
Test Driven Development is a programming methodology, which has gained quite a bit of ground in the software development world. The old practice was to jump into your code, develop all the features of your application, and assume that you are a coding god and did everything correctly. Those who were wise enough to recognize their mortality, would test their code at the end of the development process, but there were still problems inherent in this approach. First, since testing was at best an afterthought, many times it was never completed or not every aspect of the system was tested. Second, testing was expensive, both in terms of dollars and time. Good code went through planning and implementation phases already, so testing simply added a third layer to the process requiring further resources. Test Driven Development counters this old rationale by saying let the test define the system, rather than the system defining the tests. Essentially, then, planning becomes merged with testing, saving an extra phase in development.
So, the heavenly choir sings out in loud chorus and all is right with the world, correct? Not exactly. While the ideal of Test Driven Development was brilliant, its implementation left much to be desired. Everything still centered around the idea of a test, and because of that, the tests were still at least partly defined by the system. Put another way, although tests were being used to define the system, they were still tied to the system itself. If for some reason, the system had to change, any associated tests would start to fail. At that point, the developer is forced to rewrite the tests and we’re right back where we started, testing after implementation.
Behavior Driven Development
Enter Behavior Driven Development. Behavior Driven Development is not a departure from Test Driven Development, but rather, a refactoring thereof. Where Test Driven Development is about proving a piece of code works, Behavior Driven Development is about describing what a piece of code should do. It’s a subtle difference, but an important one. It’s a move from verification to specification, from testing state to testing interactions.
Process
So how does Behavior Driven Development work? It begins with a specification. A specification is an executable description of some functionality in a system. The term “executable” is used here because specifications are in fact written via executable code. However, I like to think of it based on a close synonym: actionable. A specification is an actionable description of some functionality in a system.
I should be able to take my specification and write the code for that functionality in the system with no further information required. More to the point, anyone should be able to take my specifications and implement the same system I have created. We are in fact “specifying” what our application does, how it acts, and how it behaves.
Once our specification is in place, it can be run, resulting in a failure. Failure has a negative connotation in most areas, but in Behavior Driven Development, a failure is a good thing. Nothing has been implemented yet, so the specification fails. This is a call to action. Now it’s time to implement the behavior. Having done so, the specification is run again, and this time it passes. Hooray!
The approach sounds simplistic, but it is in fact extremely powerful. Because we have developed in this way, we can now make some confident assertions. First, we have accomplished something. Our application now has functionality where before it had none. Second, we know that the code is correct and bug free. Finally, and most importantly, we know that our application does exactly what it should do.
With that surety firmly in place, we write another specification, watch it fail, implement the behavior, watch it pass, and so on. Not only does this process grant confidence every step of the way, it also serves to break down our application into manageable bits. The focus shifts from developing an entire application to developing pieces of functionality that come together to make an application.
In Conclusion
That does it for my introduction to Behavior Driven Development. I have intentionally tried to stay away from both a technical and a philosophical approach to discussing this concept for two reasons. First, others have already done that better than I can, and second, I wanted to convey the true value of using the methodology. In my next post, I’ll begin looking at rSpec, a Ruby framework for Behavior Driven Development.
Subscribe (RSS)
Hans-Eric Grönlund Says:
September 4th, 2007 at 3:48 am
This is the first time I hear about Behavior-driven development, but to me it sounds exactly like TDD - at least in the way I use TDD. I’m looking forward to your next post; comparing rSync with xUnit will probably help me chisel out the differences.
Great post!
Dev Says:
September 4th, 2007 at 4:25 am
To me sounds like functional testing :)
Peter Thomas Says:
September 4th, 2007 at 5:13 am
I agree, with the first comment, I was expecting an “aha” moment (after which I would jump on to the BDD bandwagon :) - but what you have described sounds exactly like the unit tests I write.
I would like to see something in real code, ideally compared side by side with a TDD approach - in order to be convinced that this is just not yet another “snake oil” concept.
chrisdpratt Says:
September 4th, 2007 at 10:00 am
Thank you all for your comments. Sometimes what you write makes sense to you, but you come to find out that it doesn’t necessarily make sense to others. This seems to be the case here.
Dave Astels, the front-runner advocate of BDD, explains the difference between TDD and BDD thus: “BDD is what you’re doing if you’re doing TDD really well.”
I think I made too much out of the differences between the two methodologies, but they are really quite similar. The chief and primary difference between BDD and TDD is that of semantics.
The goal in both methodologies is to test behavior rather than state. By that, I mean that we want our tests to be implementation independent. All my test should care about is that the functionality is there, not how that functionality works.
And that is where the chief problem with TDD comes. Because of its test-based nomenclature, it’s more tempting for people to test the bits and pieces of the application rather than the central functionality. BDD is a reformulation of TDD, using more behavior-specific nomenclature, based on the Sapir-Whorf theory that language influences behavior.
In other words, all BDD does is remove the word ‘test’ from the playing field, so that it’s easier to focus on the true purpose of TDD: specifying behavior.
Morning Brew #72 Says:
September 6th, 2007 at 9:36 am
[...] An Introduction to Behavior Driven Development. [...]
Meet RSpec: Your Friendly, Neighborhood BDD Framework :: Chris Pratt / <% mind.stub!(:sane?).and_return(true) %> Says:
September 23rd, 2007 at 8:05 pm
[...] An Introduction to Behavior Driven Development [...]