← Back to Django Course | Chapter 13: Testing in Django | Lesson 2 of 9

The TestCase Class Basics

TestCase is a special toolbox Django gives you that already knows how to set up and clean up a fake database for every test.

Subclassing TestCase

Django's TestCase class extends Python's built-in unittest.TestCase and adds database transaction handling, so changes made in one test never leak into another test.

Note: Always import TestCase from django.test, not from unittest directly.

Example: Subclassing TestCase

Django's TestCase class extends Python's built-in unittest.TestCase and adds database transaction handling, so changes made in one test never leak into another test.

markup
from django.test import TestCase


class ExampleTests(TestCase):
    def test_true_is_true(self):
        self.assertTrue(True)
{# 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. #}

The setUp method

setUp() runs automatically before every single test method in the class. It is the place to create objects that multiple tests need, avoiding repetition.

Note: Use setUp() for shared fixtures rather than copy-pasting object creation into every test.

Example: The setUp method

setUp() runs automatically before every single test method in the class. It is the place to create objects that multiple tests need, avoiding repetition.

markup
from django.test import TestCase
from django.contrib.auth.models import User


class UserTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user('alice', password='pass123')

    def test_user_created(self):
        self.assertEqual(self.user.username, 'alice')
{# 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. #}

Naming test methods

Django's test runner only discovers methods whose names start with test. A method named check_user() would silently never run.

Warning: Methods not starting with test are silently skipped, not flagged as errors.

Example: Naming test methods

Django's test runner only discovers methods whose names start with test. A method named check_user() would silently never run.

markup
class NamingTests(TestCase):
    def test_username_is_lowercase(self):
        self.assertEqual('alice', 'alice'.lower())
{# 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. #}
Common Mistakes
  1. Inheriting from Python's plain unittest.TestCase instead of Django's TestCase, losing automatic database rollback between tests.
  2. Forgetting that each test method runs independently, then relying on state left over from a previous test method.
  3. Putting expensive setup code inside every single test method instead of in setUp().
Chapter Summary
  • django.test.TestCase wraps each test in a database transaction that is rolled back afterward.
  • Every test class you write should subclass TestCase, not plain unittest.TestCase.
  • Test methods must start with the word test to be discovered and run.
  • setUp() runs before every test method, giving each test a clean, predictable starting point.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.