WSGI testing for Django in Nose

Testing Django applications requires setting up an appropriate environment, which is a generic procedure. If you’re using Nose and a PasteDeploy Application Factory for Django, you can use a Nose plugin that will simplify this setup. You just have to use the following option:

--with-django-wsgified=<URI-to-PasteDeploy-config>

For example:

nosetests --with-django-wsgified=config:/path/to/configuration.ini

The big advantage of this is that you’ll be able to run the test suite with different settings (e.g., to change the database backend).

If you don’t want to type that long option all the time, you can add the following to your setup.cfg file (should be in the same directory as setup.py):

[nosetests]
with-django-wsgified = config:/path/to/configuration.ini

And then you’ll just need to run nosetests.

Buildout recipe

Hard-coding the URI in a file is an option when it’s a fixed and relative path. If that’s not the case and you use Buildout [1], our recipe for the Nose plugin will solve this issue.

You could use it like this:

[test]
recipe = twod.wsgi:nose
paste_config_uri = ${URI_to_the_config}
eggs = YOUR_DISTRIBUTION

Then it will create a nosetests script where the --with-django-wsgified will be set to the value in the Buldout variable ${URI_to_the_config} by default. You’ll be able to override this URI when you run nosetests, if you ever need to.

It’s an extension to the zc.recipe.egg recipe, so you can use its additional options such as extra-paths and find-links.

Note

Make sure to install the extra dependencies for this recipe.

If you’ve added twod.wsgi as a dependency in your setup.py file, rename it to twod.wsgi[buildout]. This way, twod.wsgi will be installed along with the additional dependencies for this Buildout recipe.

If you’re installing it from easy_install, you’d need to run:

easy_install twod.wsgi[buildout]

Functional tests with WebTest

WebTest is a functional testing library for WSGI applications. It’s like the one provided by Django, but better. Among other things, it’s able to parse HTML, XML and JSON responses so you can inspect them pythonically.

To use it, you’d just need to wrap our Django-powered WSGI application around webtest.TestApp:

from webob import TestApp
from twod.wsgi import DjangoApplication

app = TestApp(DjangoApplication())

# ...

response = app.get("/")

assert "Welcome to my site" in response
assert 200 == response.status_int
assert "200 Alright then" == response.status
assert "login" in response.forms

The test application object is stateless, so it’s safe to reuse the same object for all your tests.

Skipping database setup

By default, it is going to set up a test database. If you want to run a test suite which does not need a database, you can disable it with the --no-db option:

--no-db
Do not create a test database in Django.

For example:

nosetests --no-db your_packages.tests.test_suite_without_db

Footnotes

[1]You should be using Buildout anyway!