2015-07-02 2 views
10

Я хочу иметь возможность устанавливать переменные среды в моем приложении Django для тестирования, чтобы они могли работать. Например, мои взгляды зависят от нескольких ключей API.переменные среды настройки django в тестах unittest

Есть способы для override settings during testing, но я не хочу, чтобы они были определены в settings.py, так как это проблема безопасности.

Я попытался в своей функции установки установить эти переменные среды, но это не работает, чтобы дать приложению Django значения.

class MyTests(TestCase): 
    def setUp(self): 
     os.environ['TEST'] = '123' # doesn't propogate to app 

Когда я проверить на месте, я просто есть .env файл я бегу с

foreman start -e .env web 

который поставляет os.environ со значениями. Но в Django unittest.TestCase у него нет способа (который я знаю) установить это.

Как я могу обойти это?

+2

Вы пробовали использовать [EnvironmentVarGuard] (https://docs.python.org/2/library/test.html#test.test_support.EnvironmentVarGuard)? – schillingt

+0

Да, это был правильный ответ! – lollercoaster

ответ

7

Как @schillingt отметил в комментариях, EnvironmentVarGuard был правильным способом.

from test.test_support import EnvironmentVarGuard 
from django.test import TestCase 

class MyTestCase(TestCase): 
    def setUp(self): 
     self.env = EnvironmentVarGuard() 
     self.env.set('VAR', 'value') 

    def test_something(self): 
     with self.env: 
      # ... perform tests here ... # 
      pass 

Это правильно устанавливает переменные среды для длительности заявления объект контекста with.

+1

Выдает ошибку импорта. Кроме того, в документации для EnvironmentVarGuard говорится: «Предупреждение. Пакет для тестирования предназначен только для внутреннего использования только для Python. Он задокументирован в интересах основных разработчиков Python. Любое использование этого пакета за пределами стандартной библиотеки Python не рекомендуется, поскольку упомянутый код здесь могут быть изменены или удалены без уведомления между релизами Python ». – Nate

+3

python 3 переместил его в 'из test.support import EnvironmentVarGuard'. Однако, если вы предпочитаете не зависеть от кода только для внутреннего использования, вы можете скопировать реализацию [python 2.7 EnvironmentVarGuard] (https://github.com/python/cpython/blob/2.7/Lib/test/test_support .py # L957-L1001) в ваш собственный код - это довольно просто. – medmunds

0

Я использую py.test как мой тестовый бегун, и он позволяет создать файл pytest.ini, в котором вы можете указать конкретный файл настроек, который будет использоваться во время выполнения тестов.

См документации по этому вопросу здесь:

http://pytest-django.readthedocs.org/en/latest/configuring_django.html#pytest-ini-settings

Я рекомендую py.test вообще как тест бегун, поскольку он поддерживает различные типы тестовых классов и даже простых функций, и это довольно легко установить или другой код, который работает до и после тестов.

+0

Вот как изменить файлы 'settings.py', а не переменные среды. Мои вызовы API, например AWS, и т. Д. Производятся с конструкторами, которые ищут переменные окружения, а не настройки django. – lollercoaster

+0

Вы сказали: «Есть способы переопределить настройки во время тестирования, но я не хочу, чтобы они определялись в settings.py, поскольку это проблема безопасности». Я не вижу, как определение переменных в файле настроек, которое используется * только * вашим тестовым бегуном, является проблемой безопасности. – erewok

+0

Я должен был быть яснее. Есть два вопроса. 1) безопасность, а не ведение учетных данных, 2) мой рабочий процесс с переменными окружения 'boto' и другими API-интерфейсами, поэтому я хотел бы иметь возможность использовать их. Я просто рисовал аналогию с settings.py – lollercoaster

0

Старый вопрос, но он появился в поиске Google, и ни один из существующих ответов не подходит. Если вы используете pytest, env vars можно установить/восстановить с помощью pytest's monkeypatching functionality.

13

test.support.EnvironmentVarGuard - это внутренний API, который может быть изменен с версии на версию с нарушениями (обратно несовместимыми). Фактически, весь пакет test является внутренним использованием. На странице документации тестового пакета было явно указано, что оно предназначено для внутреннего тестирования основных библиотек и НЕ открытого API. (см. ссылки ниже)

Вы должны использовать patch.dict() в стандартной библиотеке python unittest.mock. Его можно использовать в качестве менеджера контекста, декоратора или декоратора. См. Пример кода ниже, скопированного из официальной документации Python.

import os 
from unittest.mock import patch 
with patch.dict('os.environ', {'newkey': 'newvalue'}): 
    print(os.environ['newkey']) # should print out 'newvalue' 
    assert 'newkey' in os.environ # should be True 
assert 'newkey' not in os.environ # should be True 

Обновление: для тех, кто не читает документацию тщательно и, возможно, пропустили записку, прочитал больше test заметки пакет на

https://docs.python.org/2/library/test.html или

https://docs.python.org/3/library/test.html

+2

@seb в указанной вами ссылке, он привязан к классу test.test_support.EnvironmentVarGuard', другими словами, он является частью пакета 'test', который является тестовым пакетом регрессии для ** Python **. Затем прокрутите страницу ALL THE WAY UP, прочитайте заметку во второй строке сразу после названия: _Note. Пакет для тестирования предназначен только для внутреннего использования только Python. Он задокументирован в интересах основных разработчиков Python. Любое использование этого пакета за пределами стандартной библиотеки Python не рекомендуется, поскольку упомянутый здесь код может быть изменен или удален без уведомления между релизами Python._ – Devy

1

Если вы загружая переменные среды в файл settings.py Django, например:
import os ENV_NAME = os.environ.get('ENV_NAME', 'default')
Вы могли бы использовать это:
from django.test import TestCase, override_settings @override_settings(ENV_NAME="super_setting") def test_...(self):

Смежные вопросы