Django WebTest
django-webtest is a Python library that provides instant integration of Ian Bicking's WebTest with Django's testing framework. It offers a `django.test.TestCase` subclass (`django_webtest.WebTest`) that wraps a `webtest.TestApp` around the Django WSGI interface, enabling high-level functional and integration testing. The library is actively maintained, with frequent updates to ensure compatibility with the latest Django and Python versions.
Common errors
-
django.core.exceptions.ImproperlyConfigured: The WebtestAuthentication middleware must be placed after Django's AuthenticationMiddleware.
cause Incorrect ordering of middleware in `settings.py`.fixEnsure `django_webtest.middleware.WebtestAuthenticationMiddleware` is placed AFTER `django.contrib.auth.middleware.AuthenticationMiddleware` in your `MIDDLEWARE` setting. -
CSRF verification failed. Request aborted.
cause Submitting a form without a CSRF token, as django-webtest does not disable CSRF checks by default.fixInclude `{% csrf_token %}` in your Django form templates. Alternatively, for specific tests, you might need to temporarily disable CSRF middleware or manually add a valid CSRF token if directly constructing form data. -
ModuleNotFoundError: No module named 'django_webtest'
cause The `django-webtest` library is not installed in the active Python environment or there's an issue with the Python path.fixInstall the package using `pip install django-webtest`. If using a virtual environment, activate it first. For pytest-django, ensure your project's `manage.py` directory is discoverable or explicitly configured in `pytest.ini`. -
AttributeError: 'TestResponse' object has no attribute 'assertFormError'
cause Using `self.assertFormError` with `django-webtest` versions 1.9.12 or newer, which no longer support this assertion due to changes in Django 5.fixUpdate your tests to check form errors manually by inspecting `response.text`, `response.html` (e.g., using Beautiful Soup), or other WebTest methods to verify error messages.
Warnings
- breaking Starting with django-webtest 1.9.13, support for Django 3.x and 4.1 has been dropped. Ensure your Django version is supported by the installed django-webtest version.
- breaking As of django-webtest 1.9.12, the `assertFormError` method is no longer compatible. This is due to changes in Django's internal handling of form errors.
- gotcha Unlike Django's native test client, django-webtest does NOT suppress CSRF checks by default. This means missing CSRF tokens in forms will cause tests to fail with HTTP 403 Forbidden errors.
- gotcha The `click` method on a WebTest response object will not work for links that rely on JavaScript for their action (e.g., `onclick` attributes without an `href`). WebTest does not execute JavaScript.
Install
-
pip install django-webtest
Imports
- WebTest
from django_webtest import WebTest
- TransactionWebTest
from django_webtest import TransactionWebTest
Quickstart
from django_webtest import WebTest
from django.urls import reverse
class MyBasicTests(WebTest):
fixtures = ['users'] # Optional: if you need initial data, e.g., for login
def test_homepage_access(self):
# Simulate a GET request to the homepage
resp = self.app.get(reverse('home_page'))
self.assertEqual(resp.status_code, 200)
self.assertIn('Welcome', resp.text)
def test_login_form_submission(self):
# Simulate login as a specific user
login_page = self.app.get(reverse('login_page'))
form = login_page.form
form['username'] = 'testuser'
form['password'] = 'testpassword'
resp = form.submit().follow()
self.assertEqual(resp.status_code, 200)
self.assertIn('Logged in as testuser', resp.text)
def test_authenticated_page(self):
# Make an authenticated request using the user argument
user_resp = self.app.get(reverse('profile_page'), user='testuser')
self.assertEqual(user_resp.status_code, 200)
self.assertIn('User Profile for testuser', user_resp.text)