The Django Test Client
Accessing the test client
Every TestCase instance automatically has self.client, a Client object that can simulate GET and POST requests against your URLs.
Example: Accessing the test client
Every TestCase instance automatically has self.client, a Client object that can simulate GET and POST requests against your URLs.
from django.test import TestCase
class ClientTests(TestCase):
def test_client_exists(self):
self.assertIsNotNone(self.client)
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
Simulating a POST request
client.post() takes the URL and a dictionary of form data, exactly like a real browser submitting a form.
Note: Match the dictionary keys to the form field name attributes exactly.
Example: Simulating a POST request
client.post() takes the URL and a dictionary of form data, exactly like a real browser submitting a form.
def test_post_creates_object(self):
response = self.client.post('/books/add/', {'title': 'New Book'})
self.assertEqual(response.status_code, 302)
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
Logging in for protected views
client.login() simulates authentication, letting tests reach views wrapped in @login_required.
Example: Logging in for protected views
client.login() simulates authentication, letting tests reach views wrapped in @login_required.
from django.contrib.auth.models import User
class ProtectedViewTests(TestCase):
def setUp(self):
self.user = User.objects.create_user('alice', password='pass123')
def test_dashboard_requires_login(self):
self.client.login(username='alice', password='pass123')
response = self.client.get('/dashboard/')
self.assertEqual(response.status_code, 200)
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
- Assuming self.client persists login across test methods — each test method gets a fresh, logged-out client.
- Sending POST data as a plain string instead of a dictionary, which the client cannot parse correctly.
- Forgetting to call self.client.login() before testing a view that requires authentication.
- self.client is available automatically on any Django TestCase subclass.
- client.get(url) and client.post(url, data_dict) simulate real HTTP requests.
- client.login(username=..., password=...) simulates a logged-in session for protected views.
- The client never touches the network — it calls your views directly through Django's request/response cycle.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: