20

I am still using Django 1.2.1, and I think with the newer Django we don't import unittest and then do unittest.TestCase.

Illustration

import unittest
class TestThis(unittest.TestCase):

from django.utils.unittest import TestCase
class TestThis(TestCase):

from django.test import TestCase
class TestThis(TestCase):

According to PyCon2011 talk, the second one is slightly more efficient.

Here is the diagram showing the relations:

enter image description here

So django.utils.unittest and django.test inherit from either unittest or unittest2.

I am not sure if the following is correct or not. Please help editing.

 ________________________________________________________________
|  Name                   |  Django Version  |  Python Version  |
-----------------------------------------------------------------
|  unittest               |     >= 1.0       |      >= 2.6      |
-----------------------------------------------------------------
|  django.utils.unittest  |     >= 1.3       |       ??         |
-----------------------------------------------------------------
|  django.test            |     >= 1.0       |      >= 2.6      |
|   - SimpleTestCase            >= 1.4              >= 2.7      |
|   - LiveServerTestCase        >= 1.4              >= 2.7      |
-----------------------------------------------------------------

In terms of efficiency, which one of the three is better? Many Django developers mock when they test, so sometimes database are not even necessary. Is there a way not creating tables when we run manage.py test myapp.MyClass ? For older version (prior to 1.3), which one is better?

CppLearner
  • 14,204
  • 29
  • 102
  • 157

1 Answers1

15

Django's TestCase enhances unittest.TestCase with some extra features:

  • Automatic loading of fixtures.
  • Wraps each test in a transaction.
  • Creates a TestClient instance.
  • Django-specific assertions for testing for things like redirection and form errors.

Generally speaking, you should most likely be using one of Django's TestCase subclasses. Usually this will be django.test.TestCase, which, for efficiency, wraps the test in a DB transaction and uses rollback to 'undo' the test in the DB. If you need to manually manage transactions within your test, you would need to use django.test.TransactionTestCase, since you can't start / rollback a transaction within a transaction.

There are some minor caveats to using django.test.TestCase, see the note here for more information.

ALSO:

If you're just looking for a way to run your tests faster, have a look at running your tests in memory, and (if you're using South), set SOUTH_TESTS_MIGRATE = False to tell South to use a (much faster) syncdb when creating the test DB, rather than running migrations.

Community
  • 1
  • 1
Chris Lawlor
  • 41,304
  • 11
  • 45
  • 67
  • I created a django app, and i have in my test.py file, an example class inheriting from *TestCase* and I have only imported the *TestCase* from *django.test*. If I import *unittest.TestCase*, would it be a conflict? – eLRuLL Feb 05 '13 at 14:46
  • 4
    @eLRuLL yes, but you could do "from django.test import TestCase as DjangoTestCase" or something similar to resolve the conflict – Chris Lawlor Feb 07 '13 at 21:34
  • 1
    great tip, I didn't know that. – eLRuLL Feb 07 '13 at 22:14
  • The link for caveats to using `django.test.TestCase` is 404ing – krd Jul 19 '16 at 15:59