I sat in a Test Driven Development (TDD) class the other day and what I noticed was inquisitive questions and concerns among the trainees. Programmers wanted to know:
1. Where to start
2. What to test
3. What not to test
4. How much to test in one go
5. What to call their tests
6. How to understand why a test fails
There must be a better way I told myself to teach the core values behind TDD. After reading some blogs from Dan North and his contribution to this space, that’s when I discovered behavior-driven development (BDD). It has evolved out of established agile practices and is designed to make them more accessible and effective for teams new to agile software delivery. Over time, BDD has grown to encompass the wider picture of agile analysis and automated acceptance testing. Behavior-driven development is based on the concept of ubiquitous language. Ubiquitous language is a (semi-)formal language that is shared by all members of a software development team — both software developers and non-technical personnel. In this way BDD becomes a vehicle for communication between all the different roles in a software project. At its core, behavior-driven development is a specialized version of test-driven development which focuses on behavioral specification of software units. For example, Dan North proposes acceptance tests should be written using the standard agile framework of a user story and acceptance criteria should be written in terms of scenarios and implemented as classes.
The story template looks like this:
Title (one line describing the story)
Narrative:
As a [role]
I want [feature]
So that [benefit]
Acceptance Criteria: (presented as Scenarios)
Scenario 1: Title
Given [context]
And [some more context]…
When [event]
Then [outcome]
And [another outcome]…
Scenario 2: …
Now lets look at the famous ATM example by Dan North:
Story: Account Holder withdraws cash
As an Account Holder
I want to withdraw cash from an ATM
So that I can get money when the bank is closed
Scenario 1: Account has sufficient funds
Given the account balance is $100
And the card is valid
And the machine contains enough money
When the Account Holder requests $20
Then the ATM should dispense $20
And the account balance should be $80
And the card should be returned
Scenario 2: Account has insufficient funds
Given the account balance is $10
And the card is valid
And the machine contains enough money
When the Account Holder requests $20
Then the ATM should not dispense any money
And the ATM should say there are insufficient funds
And the account balance should be $20
And the card should be returned
Scenario 3: Card has been disabled
Given the card is disabled
When the Account Holder requests $20
Then the ATM should retain the card
And the ATM should say the card has been retained
Scenario 4: The ATM has insufficient funds
…
In Summary, BDD is a synthesis and refinement of practices stemming from Test Driven Development and Acceptance Test Driven Development. However, BDD augments TDD and ATDD with the following tactics:
1. Apply the “Five Why’s” principle to each proposed User Story, so that its purpose is clearly related to business outcomes.
2. Thinking “from the outside in”, in other words implement only those behaviors which contribute most directly to these business outcomes, so as to minimize waste.
3. Describe behaviors in a single notation which is directly accessible to domain experts, testers and developers, so as to improve communication.
4. Apply these techniques all the way down to the lowest levels of abstraction of the software, paying particular attention to the distribution of behavior, so that evolution remains cheap.
My next blog post in this series will focus on implementing real stories using Behavior Driven Development.