Testing registration scenario against django with lettuce and selenium webdriver
on Jan 14, 2013 by Danu
We’ll use Firefox by default since it has webdriver support built-in. If you want to use Chrome you’ll need to download the chrome driver separately.
First let's extend django default settings with lettuce specific configurations. This way we avoid running tests against dev db and declare another db to run tests against. This is actually bad, the lack of test database integration with django and the fact that lettuce server is used over LiveServerTestCase may cause reliability issues in the future (see django test database). Add
lettuce.django to INSTALLED_APPS. You can also specify the app names in LETTUCE_APPS to run tests against, so that you won’t need to type the app name as command-line parameters.
from settings import * DATABASES = INSTALLED_APPS += ( 'lettuce.django', ) LETTUCE_APPS = ( 'registerap', )
Lettuce will look for a features folder inside every installed app. For each app you want to create lettuce tests you have to create a sub folder called features. Our features are stored under
registerapp folder. The "feature" file contains scenarios, while ".py" file contains python code executed for steps used in scenarios.
Feature: Register In order to get access to app A user should be able to register Scenario: User registers Given I go to the "/register" URL When I fill in "username" with "danul" And I fill in "email" with "email@example.com" And I fill in "password1" with "test123" And I fill in "password2" with "test123" And I press "submit" Then I should see "Check your email" And I should receive an email at "firstname.lastname@example.org" with the subject "Activate your djangoproject.com account - you have 7 days!" And I activate the account Then I should see "Congratulations!" Scenario: User logs in successfully Given I go to the "/login" URL When I fill in "username" with "danul" And I fill in "password" with "test123" And I press "submit" Then I should see "Welcome, danul. Thanks for logging in."
We are importing
django_url utility function so we can easily access web pages within steps using relative urls. We also importing the email backend that sends mails to a multiprocessing queue. Because Django server runs in a different process than lettuce you are not able to use the
EMAIL_BACKEND specified in settings file, not to mention that
harvest.py is using
django.test.utils.setup_test_environment that overrides email backend to
import re from lettuce import step, world from lettuce.django import django_url from lettuce.django import mail from nose.tools import assert_equals @step(u'I go to the "(.*)" URL') : world.response = world.browser.get(django_url(url)) @step(u'I fill in "(.*)" with "(.*)"') : world.browser.find_element_by_name(field).send_keys(value) @step(u'I press "(.*)"') : button = world.browser.find_element_by_id(button_id) button.click() @step(u'I should see "(.*)"') : h1 = world.browser.find_element_by_tag_name('h1') assert_equals(h1.text, expected_response) @step(u'And I should receive an email at "([^"]*)" with the subject "([^"]*)"') : message = mail.queue.get(True, timeout=5) world.email_body = message.body assert_equals(message.subject, subject) assert_equals(message.recipients(), [address]) @step(u'And I activate the account') : activation_url = re.findall( r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', world.email_body ) world.response = world.browser.get(activation_url)
Its about setup and teardown. We setup the browser instance using webdriver. We prepare the test environment by running the django
syncdb command which creates the database tables as well loading any fixtures named
initial_data. Teardown test environment by destroying the test database. Different hooks and commands can be used, for e.g: before each scenario load specific fixtures using
from django.core.management import call_command from django.db import connection from django.conf import settings from lettuce import before, after, world from selenium import webdriver world.browser =
Running lettuce tests
All that’s left is running the tests:
python manage.py harvest tests/lettuce_selenium_tests --settings=conf.settings_lettuce
Source code for this project can be found on github:
comments powered by Disqus