More than a side salad: behaviour driven testing and test driven design in Django with Lettuce
1. more than a
side salad:
behaviour driven testing and
test driven design in Django
with Lettuce
Danielle Madeley
blogs.gnome.org/danni dannipenguin
9. As a visitor to the site
I want to create an account using my Google
login
So that I can log in without needing another
password
10. GivenI have a valid Google account
WhenI visit the siteAnd I click create account
ThenI am redirected to Google
http://www.flickr.com/photos/27369469@N08/2660160225
12. Feature: Authenticate to API
As a searcher/API user
I want to authenticate to the API
So that I can make queries
Scenario: I am not authenticated to the API
When I get the resource "/api/v3/hello/"
Then I get the response code 401
15. from lettuce import step, world
@step(r'I get the resource "([^"]*)"')
def get_resource(step, url):
"""
Make a GET request to the given URL
"""
world.response = world.client.get(url)
21. from lettuce import before, world
# import external lettuce steps
import lettuce_webdriver.webdriver
@before.all
def set_browser():
"""
Create a browser instance for use in tests.
"""
world.browser = webdriver.PhantomJS(...)
world.browser.set_window_size(1200, 800)
22. def site_url(url):
base_url = 'http://%s' % socket.gethostname()
if server.port is not 80:
base_url += ':%d' % server.port
return urlparse.urljoin(base_url, url)
@step("I visit the site")
def open_site(step):
step.given('I visit "%s"' % site_url('/'))
23. Scenario: Add consumer with blank Contact name
When I log in to admin with username "admin" and
And I click "Consumers"
And I click "Add consumer"
And I fill in "Organisation" with "OOOO"
And I fill in "Contact name" with ""
And I fill in "Contact number" with "0399999999"
And I fill in "Website" with "www.test.com"
And I press "Save"
Then I should see "This field is required"
And there should be 0 consumers in the database
25. Feature: Create new API key
As an administrator
I want to create a new API key
So that I can enable others to query API
Background:
Given I have users in the database:
| username | password | is_superuser |
| admin | secret | true |
26. Built in steps using
Django's model
introspection
Given I have users in the database:
...
Then there should be 1 consumer in the database
And consumer should be present in the database:
...
27. Which are extendable
@creates_models(User)
def create_user(step):
data = hashes_data(step)
for hash_ in data:
is_superuser = hash_.pop('is_superuser', Fals
if is_superuser:
user = User.objects.create_superuser(**ha
else:
user = User.objects.create_user(**hash_)
user.save()
reset_sequence(User)
32. write reusable scenarios
Scenario Outline: I edit a user to add a team
Given users have permissions:
| user | organisation | permission |
| peon@org.org | OrgCorp | organisation_user |
And I log in with email "<email>" through the profile serve
When I visit site page "organisation/1/admin/user/4/edit"
And I select option "Team 1" from selector "Team"
And I press "Save"
Then there should be 1 organisation member metadata in the
Then organisation member metadata should be present in the
| organisation__name | user__email | team |
| OrgCorp | peon@org.org | Team 1 |
Examples:
| email |
| god@god.org |
| superuser@org.org |
| poweruser@org.org |
36. fin ;-P
questions?
colophon This presentation was done in reveal.js using Junction, Cantarell
and Source Code Pro with photography from the Creative Commons.
Infoxchange is hiring. Come and chat to me!
blogs.gnome.org/danni dannipenguin
http://www.flickr.com/photos/mau3ry/3763640652/