lol*_*ter 25 python django environment-variables foreman
我希望能够在我的Django应用程序中设置环境变量,以便能够运行测试.例如,我的观点依赖于几个API密钥.
有一些方法可以在测试期间覆盖设置,但我不希望它们被定义,settings.py因为这是一个安全问题.
我已经尝试在我的设置函数中设置这些环境变量,但这不能为Django应用程序提供值.
class MyTests(TestCase):
def setUp(self):
os.environ['TEST'] = '123' # doesn't propogate to app
Run Code Online (Sandbox Code Playgroud)
当我在本地测试时,我只是有一个.env我运行的文件
foreman start -e .env web
Run Code Online (Sandbox Code Playgroud)
提供os.environ价值.但是在Django中unittest.TestCase它没有办法(我知道)设置它.
我怎么能绕过这个?
Dev*_*evy 34
这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
Run Code Online (Sandbox Code Playgroud)
更新:对于那些没有彻底阅读文档且可能错过了该文档的人,请阅读更多的test软件包说明
https://docs.python.org/2/library/test.html或
https://docs.python.org/3/library/test.html
lol*_*ter 12
正如@schillingt在评论中指出的那样,EnvironmentVarGuard是正确的方法.
from test.test_support import EnvironmentVarGuard # Python(2.7 < 3)
from test.support import EnvironmentVarGuard # Python >=3
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
Run Code Online (Sandbox Code Playgroud)
这会在上下文对象with语句的持续时间内正确设置环境变量.
如果您在 Django 的settings.py文件中加载环境变量,如下所示:
import os
ENV_NAME = os.environ.get('ENV_NAME', 'default')
Run Code Online (Sandbox Code Playgroud)
你可以用这个:
from django.test import TestCase, override_settings
@override_settings(ENV_NAME="super_setting")
def test_...(self):
Run Code Online (Sandbox Code Playgroud)
使用EnvironmentVarGuard不是一个好的解决方案,因为它在某些环境中会失败,而在其他环境中会起作用。请参见下面的示例。
erewok提出了一个更好的解决方案,即需要使用unittest.mockpython3中的。
假设使用unittest
from unittest.mock import patch
class TestCase(unittest.TestCase):
def setUp(self):
self.env = patch.dict('os.environ', {'hello':'world'})
def test_scenario_1(self):
with self.env:
self.assertEqual(os.environ.get('hello'), 'world')
Run Code Online (Sandbox Code Playgroud)
```