Mocking Django Storages Модель ImageField backend S3
У меня есть модель с ImageField, которая поддерживается S3Boto django-хранениями. У меня есть тест на "представление изображения", но тот факт, что он загружает изображение на S3, замедляет мой тестовый пакет.
В интересах ускорения моих тестов, какова наилучшая практика для решения этой проблемы? Должен ли я издеваться над S3Boto? Возможно, есть резервное хранилище с памятью, которое хорошо работает для тестирования (автоматическая очистка будет приятной!)?
Ответы
Ответ 1
У меня тоже была эта проблема. Я получил намного более быстрые тесты, используя dj-inmemorystorage
.
можно быстро настроить это, создав test_settings.py
в той же папке, что и ваши настройки:
from settings import *
DEFAULT_FILE_STORAGE = 'inmemorystorage.InMemoryStorage'
... и вызывая ./manage.py test --settings=project.test_settings
для запуска тестов.
Мой предпочтительный способ - настроить пользовательский тестовый прогон:
В 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',
)
Примечание. При этом также устанавливается PASSWORD_HASHER
, поскольку он значительно сокращает время создания User
. Это НЕ должно быть установлено в производстве.
В project/settings.py
:
TEST_RUNNER = 'project.test_runner.FastTestRunner'
Требования:
pip install dj-inmemorystorage
ОБНОВЛЕНИЕ: изменено с django-inmemorystorage
на dj-inmemorystorage
.
ОБНОВЛЕНИЕ 2: Удалено django-discover-runner
, поскольку оно теперь является тестовым выпуском по умолчанию в django, и исправлена ссылка на сообщение в блоге PASSWORD_HASHER
.
Ответ 2
Просто наткнулся на это, поэтому я подумал, что я поставил свое решение. В моем решении используется 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)
Некоторые gotchas - убедитесь, что у вас есть нормальная настройка MEDIA_ROOT
в настройках. с django 1.4 вы не можете использовать диспетчер контекста тестирования для переопределения MEDIA_ROOT
, поэтому для него вам потребуется отдельный конфигурационный файл настроек (https://code.djangoproject.com/ticket/17787) Это было исправлено в 1.6. Кроме того, убедитесь, что ваш upload_to работает в нормальной файловой системе, или вы получите ошибки разрешения.
Ответ 3
Я бы предложил использовать стандартное хранилище Django для тестирования, где вы можете определить настраиваемый путь для хранения и очистки этого пути в вашем тестовом наборе после выполнения. Как хранилище, так и путь можно установить в настройках и перезаписать для тестирования.
Ответ 4
Я также использую S3Boto, но для тестирования я предпочитаю использовать пользовательские настройки, которые включают использование хранилища файловой системы. Вы можете объявить свои пользовательские настройки в файле, который затем сможете импортировать и использовать в своих тестовых примерах. Тем не менее, вы можете макетировать хранилище файлов, чтобы файлы фактически не записывались на диск.
Вот образец 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',
),
)
Использование:
from django.test import TestCase
from myproject.test_settings import common_settings
@common_settings
class MyTestCase(TestCase):
"""Tests go here"""
Об издевательстве над хранилищем файловой системы вы можете проверить мой ответ здесь, на SO.