This is my introduction to behavior driven development (BDD) in Python. I have implemented a simple RESTful application using the Flask web framework. Lettuce is used enforce the mapping of user stories to tests via very simple description language called gherkin.
References:
Gherkin is the language that Lettuce understands. It is a Business Readable, Domain Specific Language that lets one describe software’s behaviour without detailing how that behaviour is implemented.
Lettuce is a Python tool for BDD that understands Gherkin. It can execute plain-text (Gherkin) functional descriptions as automated tests for Python projects.
Lettuce makes the development and testing process traceable, scalable, readable and - what is best - it allows someone who doesn’t program to describe the behavior of our system, without imagining those descriptions will automatically test the system during its development.
In this experiment, user stories are captured in user.features:
In [7]:
%%bash
cat test/features/user.features
User features define behaviors, but Python code is required to test the behaviors. These are implemented in Python in file by convention named steps.py.
If one runs lettuce without implementing the step(s), lettuce will quite helpfully provide stubs that will execute but, at this point correctly, fail. Here is an example for the step And the user 'david01' is removed.
You can implement step definitions for undefined steps with these snippets:
# -*- coding: utf-8 -*-
from lettuce import step
@step(u'And the user \'([^\']*)\' is removed')
def and_the_user_group1_is_removed(step, group1):
assert False, 'This step must be implemented'
Here are the behavior tests for user queries and deletes.
In [28]:
%%bash
pygmentize ./test/features/steps.py
In [8]:
%%bash
curl --silent localhost:5000/
In [9]:
%%bash
curl --silent localhost:5000/users
In [22]:
%%bash
curl --silent localhost:5000/users/zero00
In [13]:
%%bash
curl -i --silent -H "Accept: application/json" http://127.0.0.1:5000/users/zero00
In [15]:
%%bash
curl -i --silent -H "Accept: application/json" -X DELETE http://127.0.0.1:5000/users/zero00
In [16]:
%%bash
curl -i --silent -H "Accept: application/json" http://127.0.0.1:5000/users/zero00
In [20]:
%%bash
lettuce test/features/user.features
# Excuse the double printing. This does not happen on the CLI.