21π
I just had this problem too. I got much faster tests by using dj-inmemorystorage
.
The quick way of setting this up is by creating a test_settings.py
in the same folder as your settings:
from settings import *
DEFAULT_FILE_STORAGE = 'inmemorystorage.InMemoryStorage'
β¦and calling ./manage.py test --settings=project.test_settings
to run the tests.
My preferred way is to set up a custom test runner:
In project/test_runner.py
:
from django.conf import settings
from django.test.runner import DiscoverRunner
class FastTestRunner(DiscoverRunner):
def setup_test_environment(self):
super(FastTestRunner, self).setup_test_environment()
# Don't write files
settings.DEFAULT_FILE_STORAGE = 'inmemorystorage.InMemoryStorage'
# Bonus: Use a faster password hasher. This REALLY helps.
settings.PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
)
Note: This also sets the PASSWORD_HASHER
, because it significantly improves User
creation time. This should NOT be set in production.
In project/settings.py
:
TEST_RUNNER = 'project.test_runner.FastTestRunner'
The requirements:
pip install dj-inmemorystorage
UPDATE: changed from django-inmemorystorage
to dj-inmemorystorage
.
UPDATE 2: Removed django-discover-runner
, as itβs now the default test runner in django, and fixed the link to the PASSWORD_HASHER
related blog post.
5π
I also use S3Boto but for testing, I prefer having custom settings which include using the file system storage. You can have your custom settings declared in a file which you can then import and use in your test cases. Even so, you can mock the file storage so that the files are not actually written to disk.
Hereβs a sample test_settings.py
# myproject/myproject/test_settings.py
from django.test import override_settings
common_settings = override_settings(
DEFAULT_FILE_STORAGE='django.core.files.storage.FileSystemStorage',
PASSWORD_HASHERS=(
'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
),
)
Usage:
from django.test import TestCase
from myproject.test_settings import common_settings
@common_settings
class MyTestCase(TestCase):
"""Tests go here"""
On mocking the file system storage you can check out my answer here on SO.
- [Django]-How do you limit list objects template side, rather than view side
- [Django]-Django: How should I store a money value?
- [Django]-What is the equivalent of "none" in django templates?
4π
Just ran into this as well so I thought Iβd put my solution up. My solution uses Mock
import mock
from django.core.files.storage import FileSystemStorage
from django.test import TestCase
class ATestCase(TestCase):
def setUp(self):
# Stuff Happens
def tearDown(self):
# more Stuff
@mock.patch('storages.backends.s3boto.S3BotoStorage', FileSystemStorage)
def test_file_stuff(self):
self.assertMagicPonies(True)
Some gotchas β make sure you have a sane This was fixed in 1.6. Also, make sure your upload_to works in normal filesystem, or you will get permission errors.MEDIA_ROOT
setup in the settings. as of django 1.4, you canβt use the testing context manager to override MEDIA_ROOT
, so you need a separate settings config for it (https://code.djangoproject.com/ticket/17787)
- [Django]-Tailwindcss: fixed/sticky footer on the bottom
- [Django]-How to get two random records with Django
- [Django]-Gunicorn Connection in Use: ('0.0.0.0', 5000)
1π
I know this is a rather old thread, but Django 4.2 now offers a much simpler way with the InMemoryStorage
. You just have to override the settings to declare it, and all media file accesses will be mocked in memory:
@override_settings(STORAGES={
"default": {
"BACKEND": "django.core.files.storage.memory.InMemoryStorage",
},
})
class StorageTest(TestCase):
"""Any upload test will only use memory here"""
...
- [Django]-How can I turn Django Model objects into a dictionary and still have their foreign keys?
- [Django]-What's the recommended approach to resetting migration history using Django South?
- [Django]-After adding django-debug to App, getting "'djdt' is not a registered namespace"
0π
I would propose to use the standard Django Storage for testing, where you can a define custom path for storage and cleanup that path in your test suite once your done. Both the storage and the path can be set in the settings and overwritten for testing.
- [Django]-Django postgresql json field schema validation
- [Django]-Django Model Field Default to Null
- [Django]-Additional conditions on join in django