Django - как определить тестовую среду
Проблема кажется простой, но, к сожалению, для нее это немного сложно.
Мой вопрос заключается в следующем: как я могу обнаружить внутри представления, которое оно вызывается в тестовой среде или нет?
#pseudo_code
def my_view(request):
if not request.is_secure() and not TEST_ENVIRONMENT:
return HttpResponseForbidden()
Ответы
Ответ 1
Поместите это в свои settings.py:
import sys
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
Это проверяет, был ли второй аргумент командной строки (после ./manage.py
) test
. Затем вы можете получить доступ к этой переменной из других модулей, например:
from django.conf import settings
if settings.TESTING:
...
Есть веские причины для этого: предположим, что вы получаете доступ к некоторым бэкэнд-сервисам, кроме моделей Django и подключений к БД. Тогда вам может потребоваться узнать, когда позвонить в производственную службу и тестовую службу.
Ответ 2
Создайте свой собственный подкласс TestSuiteRunner и измените настройку или сделайте все, что вам нужно, для остальной части вашего приложения. Вы указываете тестовый бегун в своих настройках:
TEST_RUNNER = 'your.project.MyTestSuiteRunner'
В общем, вы не хотите этого делать, но он работает, если вам это абсолютно необходимо.
from django.conf import settings
from django.test.simple import DjangoTestSuiteRunner
class MyTestSuiteRunner(DjangoTestSuiteRunner):
def __init__(self, *args, **kwargs):
settings.IM_IN_TEST_MODE = True
super(MyTestSuiteRunner, self).__init__(*args, **kwargs)
Ответ 3
Просто посмотрите request.META['SERVER_NAME']
def my_view(request):
if request.META['SERVER_NAME'] == "testserver":
print "This is test environment!"
Ответ 4
Я считаю, что лучший подход - запустить ваши тесты, используя собственный файл настроек (то есть settings/tests.py). Этот файл может выглядеть так (первая строка импортирует настройки из файла настроек local.py):
from local import *
TEST_MODE = True
Затем выполните ducktyping, чтобы проверить, находитесь ли вы в тестовом режиме.
try:
if settings.TEST_MODE:
print 'foo'
except AttributeError:
pass
Ответ 5
Также существует возможность временно перезаписать настройки в unit test в Django. В некоторых случаях это может быть более легкое/чистое решение.
Вы можете сделать это в тесте:
with self.settings(MY_SETTING='my_value'):
# test code
Или добавьте его в качестве декоратора в методе тестирования:
@override_settings(MY_SETTING='my_value')
def test_my_test(self):
# test code
Вы также можете установить декоратор для всего класса тестового случая:
@override_settings(MY_SETTING='my_value')
class MyTestCase(TestCase):
# test methods
Для получения дополнительной информации проверьте документы Django: https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.override_settings
Ответ 6
Отказываясь от ответа @Tobia, я думаю, что это лучше реализовано в settings.py вот так:
import sys
try:
TESTING = 'test' == sys.argv[1]
except IndexError:
TESTING = False
Это не позволит ему поймать такие вещи, как ./manage.py loaddata test.json
или ./manage.py i_am_not_running_a_test
Ответ 7
Хотя нет официального способа проверить, находимся ли мы в тестовой среде, django на самом деле оставляет нам некоторые подсказки. По умолчанию тестер Djangos автоматически перенаправляет всю отправленную Django электронную почту в фиктивный почтовый ящик. Это достигается путем замены EMAIL_BACKEND в функции с именем setup_test_environment, которая в свою очередь вызывается методом DiscoverRunner. Итак, мы можем проверить, установлен ли settings.EMAIL_BACKEND на "django.core.mail.backends.locmem.EmailBackend". Это означает, что мы находимся в тестовой среде.
Менее хакерским решением было бы следовать примеру разработчиков, добавив нашу собственную настройку, создав подкласс DisoverRunner, а затем переопределив метод setup_test_environment.
Ответ 8
Если у вас несколько файлов настроек для разных сред, все, что вам нужно сделать, это создать один файл настроек для тестирования.
Например, ваши файлы настроек:
your_project/
|_ settings/
|_ __init__.py
|_ base.py <-- your original settings
|_ testing.py <-- for testing only
В свой файл testing.py добавьте флаг TESTING
:
from .base import *
TESTING = True
В своем приложении вы можете получить доступ к settings.TESTING
, чтобы проверить, находитесь ли вы в среде тестирования.
Для запуска тестов используйте:
python manage.py test --settings your_project.settings.testing