Подтвердить что ты не робот

Mocking Django Storages Модель ImageField backend S3

У меня есть модель с ImageField, которая поддерживается S3Boto django-хранениями. У меня есть тест на "представление изображения", но тот факт, что он загружает изображение на S3, замедляет мой тестовый пакет.

В интересах ускорения моих тестов, какова наилучшая практика для решения этой проблемы? Должен ли я издеваться над S3Boto? Возможно, есть резервное хранилище с памятью, которое хорошо работает для тестирования (автоматическая очистка будет приятной!)?

4b9b3361

Ответ 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.