Search code examples
pythondjangofixturesdjango-testing

Optimize Django tests with preloaded database


I am trying to reduce my CI usage and make my code cleaner by pre-loading my test database using a custom class.

I had multiple files/classes that looked like this:

class TestSomething(TestCase):
    def setUp(self):
        User.objects.create(...)

    def test_something(self):
        pass

I converted them into:

class TestSomething(PreloadedTestCase):
    def test_something(self):
        pass

with a common PreloadedTestCase class:

class TestSomething(TestCase):
    def setUp(self):
        User.objects.create(...)

This does make the code cleaner and removes a lot of duplicate lines, but it seems to increase the CI execution time.

Is PreloadedTestCase.setUp() run multiple times? If so, how can I have a common class that is run only once against the database?
I looked into fixtures but it is only populating the database, I would have to query it to access my objects in the tests.


Solution

  • setUp runs for each test case, so you're creating the data for each case here.

    setUpClass runs once for each class (better)

    setUpModule runs for each module

    Don't forget the teardown stuff if you need to.

    https://docs.python.org/3/library/unittest.html

    I find pytest with pytest-django better for this stuff as it makes fixtures easier to use.

    Alternatively, you can set up alternative databases to use for Django testing - some good info here: https://docs.djangoproject.com/en/4.0/topics/testing/advanced/