Chapter 6: Django Add Test View
Django Add Test View: Many beginners skip testing because “it works on my machine”… until it doesn’t, or until you hand the project to someone else, or until you deploy and everything breaks in production.
Today we’ll do it slowly, practically, and with zero theory overload — like I’m sitting next to you creating the first test together.
Goal for Today
We will:
- Create one very simple test view (just returns “Test page works!”)
- Write two basic tests for it using Django’s built-in test client
- Run the tests and see green output
- Understand folder structure & best naming habits
- See how to test a real view (your polls index) later
Step 1: Where Do Tests Live?
Django expects tests in files that:
- Are inside your app
- Start with test_ (e.g. tests.py, test_views.py, test_models.py)
Default file created by startapp:
|
0 1 2 3 4 5 6 7 |
polls/ ├── tests.py ← you can use this for small apps |
Better practice (2026 standard) — split tests by topic:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
polls/ ├── tests/ │ ├── __init__.py │ ├── test_models.py │ ├── test_views.py ← we create this now │ └── test_forms.py (later) |
Let’s do that.
|
0 1 2 3 4 5 6 7 8 9 |
cd polls mkdir tests touch tests/__init__.py touch tests/test_views.py |
Delete or leave empty the old tests.py — we won’t use it.
Step 2: Create a Tiny Test View (Just for Learning)
Open polls/views.py and add this at the bottom (or in a new file if you prefer):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# polls/views.py def test_page(request): """Super simple view only used for learning tests""" return HttpResponse( "<h1 style='color: green; text-align: center; margin: 100px;'>" "✅ Test view is working! You can now write tests! 🚀" "</h1>" ) |
Step 3: Add URL for the Test View
In polls/urls.py:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
urlpatterns = [ # ... your existing paths ... # Only for learning – you can remove later path('test-view/', views.test_page, name='test-page'), ] |
Visit http://127.0.0.1:8000/polls/test-view/ → should see green message.
Step 4: Write Your First Django Test
Open polls/tests/test_views.py
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from django.test import TestCase, Client from django.urls import reverse class SimpleViewTests(TestCase): """ Very basic tests to understand how Django's test client works. """ def setUp(self): """Runs before every test method""" self.client = Client() # fake browser def test_test_page_exists_and_returns_200(self): """Does /polls/test-view/ exist and return status 200?""" response = self.client.get('/polls/test-view/') self.assertEqual(response.status_code, 200) self.assertContains(response, "Test view is working!") self.assertContains(response, "✅") # emoji test def test_test_page_using_named_url(self): """Same thing but using reverse() – better style""" url = reverse('polls:test-page') # using app_name + name response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn(b"Test view is working!", response.content) self.assertTemplateUsed(response, None) # no template → None def test_test_page_has_correct_content_type(self): """Just checking headers – good habit""" response = self.client.get(reverse('polls:test-page')) self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') |
Step 5: Run the Tests!
Two ways:
Way A – Run only polls app tests
|
0 1 2 3 4 5 6 |
python manage.py test polls |
Way B – Run everything (recommended when you have many apps)
|
0 1 2 3 4 5 6 |
python manage.py test |
You should see something beautiful like:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Found 3 test(s). Creating test database for alias 'default'... System check identified no issues (0 silenced). ... test_test_page_exists_and_returns_200 (polls.tests.test_views.SimpleViewTests) ... ok test_test_page_has_correct_content_type (polls.tests.test_views.SimpleViewTests) ... ok test_test_page_using_named_url (polls.tests.test_views.SimpleViewTests) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.015s OK Destroying test database for alias 'default'... |
Green = success 🎉
Step 6: Bonus – Test Your Real Polls Index View
Now let’s test something useful.
Add this to polls/tests/test_views.py:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class PollsIndexViewTests(TestCase): def test_index_page_returns_200(self): response = self.client.get(reverse('polls:index')) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'polls/index.html') self.assertContains(response, "Latest Polls") # whatever text you have def test_index_shows_no_polls_message_when_empty(self): # Make sure database is empty for this test response = self.client.get(reverse('polls:index')) self.assertContains(response, "No polls available") |
Run again → python manage.py test polls
Best Practices & Quick Reference Table (2026 Style)
| Thing to test | Method / Assertion | Example line |
|---|---|---|
| Status code | assertEqual(response.status_code, 200) | Check page loads |
| Contains text | assertContains(response, “Hello”) | Check important phrase exists |
| Template used | assertTemplateUsed(response, ‘polls/index.html’) | Verify correct template |
| Redirect | assertRedirects(response, ‘/other-url/’) | After POST or login |
| No content | self.assertEqual(response.content, b”) | Empty response |
| Context variable | self.assertEqual(response.context[‘key’], value) | Check data passed to template |
Common Beginner Pain Points & Fixes
- ImportError: No module named ‘polls.tests’ → Forgot __init__.py in tests/ folder
- Reverse for ‘test-page’ not found → Forgot app_name = ‘polls’ in polls/urls.py
- Database is not empty → Tests run in temporary test database — real db is untouched
- Tests fail randomly → You modified real database in shell → always use TestCase (resets db)
Your Mini Homework Right Now
- Create polls/tests/test_views.py with the three simple tests above
- Run python manage.py test polls
- See green output
- Add one more test: check that /polls/test-view/ contains the emoji “✅”
- (Optional) Break the view on purpose (change status to 404) → see test become red → fix it
Tell me what feels next:
- “Green! Now show me how to test models (create, save, methods)”
- “How to test POST requests (voting form)”
- “I want to use pytest instead of unittest – example”
- “Got red test – here is the error message”
- Or finally ready for: “Let’s implement the voting view + form + atomic vote increment”
You just wrote your first real Django tests — this habit will make you 10× better developer in the long run. Super proud of you — let’s keep the momentum! 🚀🇮🇳
