BDD - TDD in a BDD Way


Advertisements

In TDD, the term “Acceptance Tests” is misleading. Acceptance tests actually represent the expected behavior of the system. In Agile practices, collaboration of the whole team and interactions with the customer and other stakeholders is emphasized. This has given rise to the necessity of usage of terms that are easily understood by everyone involved in the project.

TDD makes you think about the required Behavior and hence the term ‘Behavior’ is more useful than the term ‘Test’. BDD is Test Driven Development with a vocabulary that focuses on behavior and not tests.

In the words of Dan North, “I found the shift from thinking in tests to thinking in behavior so profound that I started to refer to TDD as BDD, or Behavior Driven Development.” TDD focuses on how something will work, BDD focuses on why we build it at all.

BDD answers the following questions often faced by the developers −

Question Answer
Where to start? outside-in
What to test? User Stories
What not to test? anything else

These answers result in the story framework as follows −

Story Framework

As a [Role]

I want [Feature]

so that [Benefit]

This means, ‘When a Feature is executed, the resulting Benefit is to the Person playing the Role.

BDD further answers the following questions −

Question Answer
How much to test in one go? very little-focused
What to call their tests? sentence template
How to understand why a test fails documentation

These answers result in the Example framework as follows −

Example Framework

Given some initial context,

When an event occurs,

Then ensure some outcomes.

This means, ‘Starting with the initial context, when a particular event happens, we know what the outcomes should be.’

Thus, the example shows the expected behavior of the system. The examples are used to illustrate different scenarios of the system.

Story and Scenarios

Let us consider the following illustration by Dan North about an ATM system.

Story

As a customer,

I want to withdraw cash from an ATM,

so that I do not have to wait in line at the bank.

Scenarios

There are two possible scenarios for this story.

Scenario 1 − Account is in credit

Given the account is in credit

And the card is valid

And the dispenser contains cash

When the customer requests cash

Then ensure the account is debited

And ensure cash is dispensed

And ensure the card is returned

Scenario 2 − Account is overdrawn past the overdraft limit

Given the account is overdrawn

And the card is valid

When the customer requests cash

Then ensure a rejection message is displayed

And ensure cash is not dispensed

And ensure the card is returned

The event is same in both the scenarios, but the context is different. Hence, the outcomes are different.

Development Cycle

The Development Cycle for BDD is an outside-in approach.

Step 1 − Write a high-level (outside) business value example (using Cucumber or RSpec/Capybara) that goes red. (RSpec produces a BDD framework in the Ruby language)

Step 2 − Write a lower-level (inside) RSpec example for the first step of implementation that goes red.

Step 3 − Implement the minimum code to pass that lower-level example, see it go green.

Step 4 − Write the next lower-level RSpec example pushing towards passing Step 1 that goes red.

Step 5 − Repeat steps Step 3 and Step 4 until the high-level example in Step 1 goes green.

Note − The following points should be kept in mind −

  • Red/green state is a permission status.

  • When your low-level tests are green, you have the permission to write new examples or refactor existing implementation. You must not, in the context of refactoring, add new functionality/flexibility.

  • When your low-level tests are red, you have permission to write or change implementation code only for making the existing tests go green. You must resist the urge to write the code to pass your next test, which does not exist, or implement features you may think are good (customer would not have asked).

Advertisements