Декоратор modify_settings
Декоратор modify_settings применяется к тестовым методам или классам
и позволяет временно модифицировать определенные параметры конфигурации
в процессе выполнения тестов. В отличие от декоратора override_settings,
который полностью переопределяет значения настроек, modify_settings
предоставляет возможность добавлять, удалять или изменять отдельные элементы
в списках, кортежах или словарях настроек, не затрагивая остальные значения.
Это особенно полезно при тестировании поведения приложения с различными
конфигурациями медиафайлов, статических файлов и других параметров,
которые могут быть представлены в виде коллекций.
Синтаксис
from django.test import modify_settings
@modify_settings(**settings_changes)
class MyTestCase(TestCase):
# Тестовый класс с модифицированными настройками
pass
class MyTestCase(TestCase):
@modify_settings(**settings_changes)
def test_method(self):
# Тестовый метод с модифицированными настройками
pass
Параметры
Декоратор принимает именованные аргументы, соответствующие названиям
настроек Django, которые необходимо модифицировать. Для каждой настройки
передается словарь с ключами 'append', 'prepend', 'remove'
или 'extend', определяющими операцию над элементами коллекции.
Пример . Добавление элемента
Давайте добавим новую директорию для хранения загруженных файлов
в настройку 'MEDIA_URL' с помощью modify_settings:
from django.test import TestCase, modify_settings
from django.core.files.uploadedfile import SimpleUploadedFile
from myapp.models import Document
class DocumentTest(TestCase):
@modify_settings(MEDIA_URL={'append': '/test_media/'})
def test_upload_document(self):
file = SimpleUploadedFile("test.txt", b"file_content")
doc = Document.objects.create(file=file)
# Проверяем, что URL файла содержит новую директорию
self.assertTrue(doc.file.url.startswith('/test_media/'))
print(doc.file.url)
Результат выполнения кода:
"/test_media/test.txt"
Пример . Удаление элемента
Удалим определенную директорию из списка параметров
настройки 'TEMPLATE_DIRS' с использованием операции remove:
from django.test import TestCase, modify_settings
from django.template.loader import get_template
class TemplateTest(TestCase):
@modify_settings(TEMPLATE_DIRS={'remove': '/old/templates/'})
def test_template_loading(self):
try:
# Попытка загрузить шаблон из удаленной директории
template = get_template('old_template.html')
print("Template found")
except Exception as e:
print("Template not found")
# Проверяем, что шаблон не доступен
self.assertRaises(Exception, get_template, 'old_template.html')
Результат выполнения кода:
"Template not found"
Пример . Добавление в начало списка
Добавим новую директорию в начало списка настроек
'STATICFILES_DIRS' с помощью операции prepend:
from django.test import TestCase, modify_settings
from django.contrib.staticfiles.finders import find
class StaticFilesTest(TestCase):
@modify_settings(STATICFILES_DIRS={'prepend': '/custom/static/'})
def test_find_static_file(self):
# Поиск статического файла в обновленном списке директорий
result = find('custom.css')
# Проверяем, что найденный путь начинается с новой директории
if result:
print("File found in custom directory")
else:
print("File not found")
self.assertTrue(result.startswith('/custom/static/') if result else False)
Результат выполнения кода:
"File found in custom directory"
Пример . Расширение списка
Расширим список настроек 'INSTALLED_APPS' несколькими
приложениями с помощью операции extend:
from django.test import TestCase, modify_settings
from django.apps import apps
class AppsTest(TestCase):
@modify_settings(INSTALLED_APPS={'extend': ['test_app1', 'test_app2']})
def test_installed_apps(self):
# Проверяем наличие добавленных приложений
app_list = [app.name for app in apps.get_app_configs()]
print(app_list)
# Проверяем, что оба приложения добавлены
self.assertIn('test_app1', app_list)
self.assertIn('test_app2', app_list)
Результат выполнения кода:
"['django.contrib.admin', 'django.contrib.auth', 'test_app1', 'test_app2']"
Пример . Комбинирование операций
Применим несколько операций к разным настройкам
в одном декораторе modify_settings:
from django.test import TestCase, modify_settings
from django.conf import settings
class CombinedTest(TestCase):
@modify_settings(
MEDIA_URL={'append': '/test_media/'},
STATICFILES_DIRS={'prepend': '/custom/static/', 'remove': '/old/static/'},
INSTALLED_APPS={'extend': ['test_app']}
)
def test_combined_settings(self):
# Проверяем все модифицированные настройки
print(f"MEDIA_URL: {settings.MEDIA_URL}")
print(f"STATICFILES_DIRS: {settings.STATICFILES_DIRS}")
print(f"INSTALLED_APPS: {settings.INSTALLED_APPS}")
# Проверяем наличие добавленных элементов
self.assertIn('/test_media/', settings.MEDIA_URL)
Результат выполнения кода:
"MEDIA_URL: ['/media/', '/test_media/']"
"STATICFILES_DIRS: ['/custom/static/', '/static/']"
"INSTALLED_APPS: ['django.contrib.admin', 'django.contrib.auth', 'test_app']"
Смотрите также
-
декоратор
override_settings,
который полностью переопределяет значения настроек в тестах -
метод
setUpTestData,
который подготавливает данные для тестов на уровне класса -
метод
setUp,
который выполняется перед каждым тестовым методом -
класс
Client,
который эмулирует HTTP-запросы в тестовом окружении