[Solved]-Django cache isolation when running tests in parallel


You don’t need "an isolated section of the cache", just to clear cache between tests.

Here are a few ways.

1. Subclass TestCase

The question mentions this is not desired, but I should still mention this proper way.

from django.core.cache import cache
from django.test import TestCase

class CacheClearTestCase(TestCase):

    def tearDown(self):
        # super().tearDown()

2. Patch TestCase.tearDown

Assuming subclasses that override tearDown call super().tearDown(), you could do this.

Add this in manage.py before execute_from_command_line(sys.argv):

if sys.argv[1] == 'test':
    from django.test import TestCase
    from django.core.cache import cache
    TestCase.tearDown = cache.clear

3. Subclass TestSuite

You can clear the cache after each test by subclassing TestSuite to override _removeTestAtIndex and setting DiscoverRunner.test_suite to that subclass.

Add this in manage.py before execute_from_command_line(sys.argv):

if sys.argv[1] == 'test':
    from unittest import TestSuite
    from django.core.cache import cache
    from django.test.runner import DiscoverRunner

    class CacheClearTestSuite(TestSuite):
        def _removeTestAtIndex(self, index):

    DiscoverRunner.test_suite = CacheClearTestSuite

Why you don’t need an isolated section of the cache

To be clear, this is not a problem caused by running tests in parallel.

From https://docs.djangoproject.com/en/4.0/ref/django-admin/#cmdoption-test-parallel:

--parallel [N]

Runs tests in separate parallel processes.

From https://docs.djangoproject.com/en/4.0/topics/cache/#local-memory-caching-1:

Note that each process will have its own private cache instance, which means no cross-process caching is possible.



The easiest solution would be to have a separate settings file for tests that you can load in manage.py. This can also import all of your default settings.


    settings = 'my_project.test_settings' if 'test' in sys.argv else 'my_project.settings'
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings)


from .settings import *  # import default settings

# setting overrides here

    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "[random_string]",

If you need to do more settings overrides, especially for multiple environments, I would recommend using something like django-configurations.


Leave a comment