Functional tests with lettuce and django test client
on Feb 01, 2013 by Danu
When running a functional test, you fire up “browser” and do the "same" actions as a real user (or API client). There are different “browsers” for testing your applications, some of them are real, like selenium and some of them are less real, like django test client. Depending on the context, each of them has its pros and cons.
- selenium is a browser-driving library, opens a real browser and tests rendered HTML alongside with behavior of Web pages. Write selenium tests for Ajax, other JS/server interactions.
A complete test suite should contain both test types.
Functional tests and Django
Write functional/integration/system (has more names than it needs) tests for views. Unit testing the view is hard because views have many dependencies (templates, db, middleware, url routing etc).
You should definitely have django functional tests but chances are you should have fewer than you have now. See the software testing pyramid by Alister Scott which provides solid approach to automated testing and shows the mix of testing a team should aim for.
- test that the whole integrated system works, catch regressions
- they tend to be slow
- will catch bugs that unit tests will not, but it's harder to debug
- write fewer (more unit tests)
So what can you test with django-test client ?
- the correct view is executed for a given url
- simulate post, get, head, put etc. requests
- the returned content has the expected values (you can use beautiful soup, lxml or html5lib for parsing the content)
Example of functional test with lettuce and django test client
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 | username | email | password1 | password2 | | danul | firstname.lastname@example.org | test123 | test123 | And I submit the data Then I should see "Check your email" And I should receive an email at "email@example.com" with the subject "Activate your djangoproject.com account - you have 7 days!" And I activate the account Then I should see "Congratulations!" Scenario: Users login Given following users exist | username | password | | danu | test123 | | lulu | test123 | When I go to the "/login/" URL And I login as user "danu" Then I should see "Welcome, danu. Thanks for logging in."
import re from bs4 import BeautifulSoup from lettuce import * from django.core import mail from nose.tools import assert_equals from django.contrib.auth.models import User response = world.html = for data in step.hashes: world.data = data world.response = html = expected_text = . activation_url = world.response = for user_hash in step.hashes: user_data = password = user, created = if not . : world.response =
import logging from django.conf import settings from django.core.management import call_command from django.test import Client from django.db import connection #from django.test.utils import setup_test_enviroment, teardown_test_environment from lettuce import * world.browser = try: from south.management.commands import patch_for_test_db_setup except ImportError: pass # Setup test environment / called by harvest.py #setup_test_enviroment() world.testdb = # Tear Down the test environment / called by harvest.py #teardown_test_enviroment()
What's next ?
Be a good person and write functional tests. Functional testing is something that every app needs, no testing strategy is complete without high-level tests to ensure the entire programming system works together.
Source code for this article:
comments powered by Disqus