Django: Testing with twill

After putting it off again and again, I decided that it would be finally time to make an effort and start writing some actual tests for my views (rather than just the code behind them). Beyond Django’s neat, but somewhat limited test client, the tool to do this seems to be twill.

Twill supports a WSGI intercept that can be hooked up to Django, bypassing the need to go through the network. There’s an entry on django snippets that shows how to use this in context of unit tests.

I’ve slightly improved upon it to remove the need to deal with the local dummy host in urls. I also added a login/logout feature, as known from the Django’s own test client. The result can be found on BitBucket.

Quick example:

from djutils.test import twill

# install the wsgi hook
twill.setup()

try:
    # those will go to Django
    twill.go('/')
    twill.follow('login')
    twill.code(200)

    # once we're browsing away...
    twill.go('http://google.com')
    # ...urls will be relative to that
    twill.go('/services')
    # now at http://google.com/services

    # default=True brings us back to Django
    twill.go('/list', default=True)

    # you can also pass along reverse args
    twill.go('proj.app.views.func', args=[1,2,3])

    # login as some user
    twill.login(username="foo", passwort="bar")
    twill.go('/django_admin')
    twill.logout()

    # alternative: login without credentials
    any_admin = User.objects.filter(is_superuser=True)[0]
    twill.login(user=any_admin)
finally:
    twill.teardown()

For the benefit of people searching for this, I should also mention that when calling twill.setup(), a workaround is applied to make twill function with documents documents that identify themselves as XHTML. Per default, twill explicitly fails on those with a “Not viewing html” error. Looking at the source, this is apparently because support for XHTML is considered incomplete and/or broken. However, at least for two XTHML sites of mine everything seems to work just fine.

Finally, I recommend you set DEBUG_PROPAGATE_EXCEPTIONS = True while testing with twill, as explained here. Otherwise, not only will debugging tests be more difficult, in some instances tests failures may easily go unnoticed (imagine you’re testing for string containment, but inadvertently dealing with your 404 or 500 error page).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s