7👍
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()
cache.clear()
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):
super()._removeTestAtIndex(index)
cache.clear()
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.
0👍
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.
manage.py
settings = 'my_project.test_settings' if 'test' in sys.argv else 'my_project.settings'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings)
test_settings.py
from .settings import * # import default settings
# setting overrides here
CACHES = {
"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.
- Django: How to call management custom command execution from admin interface?
- How to get the primary key id that is auto generated in Django Models