django unit tests without a db django unit tests without a db django django

django unit tests without a db


You can subclass DjangoTestSuiteRunner and override setup_databases and teardown_databases methods to pass.

Create a new settings file and set TEST_RUNNER to the new class you just created. Then when you're running your test, specify your new settings file with --settings flag.

Here is what I did:

Create a custom test suit runner similar to this:

from django.test.simple import DjangoTestSuiteRunnerclass NoDbTestRunner(DjangoTestSuiteRunner):  """ A test runner to test without database creation """  def setup_databases(self, **kwargs):    """ Override the database creation defined in parent class """    pass  def teardown_databases(self, old_config, **kwargs):    """ Override the database teardown defined in parent class """    pass

Create a custom settings:

from mysite.settings import *# Test runner with no database creationTEST_RUNNER = 'mysite.scripts.testrunner.NoDbTestRunner'

When you're running your tests, run it like the following with --settings flag set to your new settings file:

python manage.py test myapp --settings='no_db_settings'

UPDATE: April/2018

Since Django 1.8, the module django.test.simple.DjangoTestSuiteRunner were moved to 'django.test.runner.DiscoverRunner'.

For more info check official doc section about custom test runners.


Generally tests in an application can be classified in to two categories

  1. Unit tests, these test the individual snippets of code in insolation and do not require to go to the database
  2. Integration test cases which actually go to the database and test the fully integrated logic.

Django supports both unit and integration tests.

Unit tests, do not require to setup and tear down database and these we should inherit from SimpleTestCase.

from django.test import SimpleTestCaseclass ExampleUnitTest(SimpleTestCase):    def test_something_works(self):        self.assertTrue(True)

For integration test cases inherit from TestCase in turn inherits from TransactionTestCase and it will setup and tear down the database before running each test.

from django.test import TestCaseclass ExampleIntegrationTest(TestCase):    def test_something_works(self):        #do something with database        self.assertTrue(True)

This strategy will ensure that database in created and destroyed only for the test cases that access the database and therefore tests will be more efficient


From django.test.simple

  warnings.warn(      "The django.test.simple module and DjangoTestSuiteRunner are deprecated; "      "use django.test.runner.DiscoverRunner instead.",      RemovedInDjango18Warning)

So override DiscoverRunner instead of DjangoTestSuiteRunner.

 from django.test.runner import DiscoverRunner class NoDbTestRunner(DiscoverRunner):   """ A test runner to test without database creation/deletion """   def setup_databases(self, **kwargs):     pass   def teardown_databases(self, old_config, **kwargs):     pass

Use like that :

python manage.py test app --testrunner=app.filename.NoDbTestRunner