Behavior Driven Development
First published at Friday 8 March 2013
Warning: This blog post is more then 11 years old – read and use with care.
Behavior Driven Development
While unit, integration and system tests - especially combined with the methodology of Test Driven Development (TDD) - are great ways to push the technical correctness of an application forward, they miss out one important aspect: the customer. None of these methods verify that developers actually implement what the customer desires. Behavior Driven Development (BDD) can help to bridge this gap.
The methodology of BDD is actually derived from TDD. Instead of writing a test for a single code unit upfront, an acceptance test for a certain behavior is formulated. More important, the test case is formulated in the ubiquitous language of the project, allowing non-technical persons to read it as the specification of the desired feature.
In the following I want to outline the methodology of BDD from a developer's perspective.
Example
So much for theory. In practice I prefer to explain things on the basis of examples. So here is an acceptance test:
Feature: The existing CFPs should be listed
As a visitor I want to get a listing of all existing CFPs.
Scenario: If there are no CFPs, I see an empty list.
Given there are no CFPs
When I view "CFP Listing"
Then I see 0 CFPs listed
The snippet above shows an acceptance test formulated in a language that is based upon the Gherkin framework for Domain Specific Languages (DSLs). The first lines are narrative, documenting the feature to be tested. They do not fulfil any technical purpose, think of it as if it was a class level doc block.
What follows is the definition of a specific scenario within the feature. A scenario is basically a user story, as you probably recognize it from your agile development mode. Again, the introductory sentence is documentation and not processed.
The block following afterwards is the actual test case. These three sentences are on the one hand human readable. On the other hand, they are structured so simple and generic that they can be processed by a computer with very little effort. The first word on every line is a keyword from the Gherkin language, while Given
indicates a precondition, the When
part indicates the test stimulus and Then
formulates an expectation.
The wonderful thing about this specification is that your customer can actually read and verify it. You can write down what you, as a developer, understood how your customer wants the system to behave. You can send the specification to her/him and ask her/him if this is exactly what she/he desires. If she/he agrees, you can start implementing right away and verify your progress against the specification, as it is executable through a BDD test tool.
Possibly, if you have a technically skilled customer and train him quite a bit, he will probably even be able to adjust scenarios or even write some on his own.
Behat
The Gherkin example from above is almost useless without a proper tool to execute it. Of course, there is no tool that can do it right away, because no software can understand the project specific sentences. However, frameworks exist that offer you a basis. For the PHP world, the toolkit of choice is called Behat.
Behat provides you with the basic infrastructure for BDD and enables you to easily work with custom sentences. Specifically, you create a so-called FeatureContext
for your test cases that contain a method for every sentence in your projects ubiquitous language. For example:
class ListingFeatureContext extends BehatContext
{
// ...
/**
* @Given /^there are no CFPs$/
*/
public function thereAreNoCfps()
{
$this->cleanupDatabase();
}
}
The extract from the ListingFeatureContext
above shows the method that reacts to the sentence Given there are no CFPs
. Using an annotation, Behat connects the method to the sentence. Whenever it discovers that sentence in a test scenario, it will execute the method.
Rationale
Of course, the examples shown above are only very rudimentary, missing e.g. variables and other advanced features. However, they should have explained what BDD is all about: Communication. Especially in teams which follow the Domain Driven Design (DDD) approach, a ubiquitous language for the project domain is already practiced. Toolkits such as Behat provide you with the environment to express expectations in this language and make these executable.
The two essential ideas behind this are a) to ease communication with the client and b) to bridge the gap between (important!) tests for technical correctness and business expectations.
Conclusion
BDD is an interesting approach that can work especially well for projects that build on extensive business logic and such that follow Domain Driven Design. Besides that, Behat can become a tool of choice for acceptance tests also in respect to its integration with Mink and Symfony2.
What are your experiences with BDD and with Behat?
Subscribe to updates
There are multiple ways to stay updated with new posts on my blog: