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