Behavior Driven Development, also known as BDD, is a concept developed by Dan North and is based on a popular and well adopted TDD. As in Dan’s words –
‘BDD is a second-generation, outside–in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.’
BDD provides a framework where QA, Business Analysts and other stake-holders communicate and collaborate on sotware development. While TDD emphasized on developing tests for unit piece of code. BDD insists on developing tests for business scenarios or use cases or behavioral specification of software being developed. According to Dan, BDD tests should be written as user stories ‘As a [role] I want [feature] so that [benefit]’ and Acceptance criteria should be defined as ‘Given [initial context], when [event occurs], then [ensure some outcomes].‘
lettuce is typically used in Python to implement BDD. This blog covers the installation of lettuce on Ubuntu and its application with an example of fibonacci function
Installation
buntu@ubuntu:~$ sudo pip install lettuce
[sudo] password for buntu:
Downloading/unpacking lettuce
Downloading lettuce-0.2.9.tar.gz (40Kb): 40Kb downloaded
Running setup.py egg_info for package lettuce
Downloading/unpacking sure (from lettuce)
Downloading sure-1.0.6.tar.gz
Running setup.py egg_info for package sure
Downloading/unpacking fuzzywuzzy (from lettuce)
Downloading fuzzywuzzy-0.1.tar.gz
Running setup.py egg_info for package fuzzywuzzy
Installing collected packages: fuzzywuzzy, lettuce, sure
Running setup.py install for lettuce
Installing lettuce script to /usr/local/bin
Running setup.py install for sure
Running setup.py install for fuzzywuzzy
Successfully installed lettuce
Setup
Let’s first create a directory structure that looks like this
buntu@ubuntu:~$ tree lettucetests/
lettucetests/
|– features
| |– fib.feature
| |– test.py
`– test.feature
1 directory, 3 files
Define Features
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Feature: Compute fibonacci | |
In order to play with Lettuce | |
As beginners | |
We'll implement fibonacci | |
Scenario: Fibonacci of 0 | |
Given I have the number 0 | |
When I compute its fibonacci | |
Then I see the number 1 | |
Scenario: Fibonacci of 1 | |
Given I have the number 1 | |
When I compute its fibonacci | |
Then I see the number 1 | |
Scenario: Fibonacci of 2 | |
Given I have the number 2 | |
When I compute its fibonacci | |
Then I see the number 2 | |
Scenario: Fibonacci of 3 | |
Given I have the number 3 | |
When I compute its fibonacci | |
Then I see the number 3 | |
Scenario: Fibonacci of 4 | |
Given I have the number 4 | |
When I compute its fibonacci | |
Then I see the number 5 |
Write Tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from lettuce import * | |
@step('I have the number (\d+)') | |
def have_the_number(step, number): | |
world.number = int(number) | |
@step('I compute its fibonacci') | |
def compute_its_fibonacci(step): | |
world.number = fibonacci(world.number) | |
@step('I see the number (\d+)') | |
def check_number(step, expected): | |
expected = int(expected) | |
assert world.number == expected | |
def fibonacci(number): | |
number = int(number) | |
if (number == 0) or (number == 1): | |
return 1 | |
else: | |
return fibonacci(number–1) + fibonacci(number–2) | |
~ |