django 在单元测试中设置环境变量
django setting environment variables in unittest tests
我希望能够在我的 Django 应用程序中设置环境变量,以便能够进行测试 运行。例如,我的观点依赖于几个 API 键。
有一些方法可以 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
中,它没有办法(据我所知)来设置它。
我该如何解决这个问题?
我使用 py.test
作为我的测试运行器,它允许您创建一个 pytest.ini
文件,您可以在其中指定要在 运行 测试时使用的特定设置文件。
在此处查看相关文档:
http://pytest-django.readthedocs.org/en/latest/configuring_django.html#pytest-ini-settings
我一般推荐 py.test 作为测试运行器,因为它支持不同类型的测试 类 甚至是简单的功能,并且设置 fixture 或其他运行之前的代码非常容易并经过测试。
正如@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
这会在上下文对象 with
语句期间正确设置环境变量。
老问题,但它出现在 Google 搜索中,现有答案都不合适。如果您使用的是 pytest,环境变量可以是 set/restored 使用 pytest's monkeypatching functionality.
test.support.EnvironmentVarGuard
是一个内部的 API,可能会随着版本的改变而改变(向后不兼容)。 事实上,整个 test
包仅供内部使用。 在测试包文档页面上明确说明它用于核心库的内部测试,而不是 public API。 (见下面的链接)
您应该在 python 的标准库 unittest.mock
中使用 patch.dict()
。它可以用作上下文管理器、装饰器或 class 装饰器。请参阅下面从官方 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
软件包说明
如果您像这样在 Django 的 settings.py
文件中加载环境变量:
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):
最初,我的环境变量 PARTNER_CODE
设置为 wow
。
我可以使用以下方法更改环境变量:
from test.support import EnvironmentVarGuard
with EnvironmentVarGuard() as env:
env['PARTNER_CODE'] = 'sos'
现在我的环境变量 PARTNER_CODE
显示 sos
。
使用 EnvironmentVarGuard
不是一个好的解决方案,因为它在某些环境中失败而在其他环境中有效。请参阅下面的示例。
erewok 提出的更好的解决方案需要使用 python3 中的 unittest.mock
。
假设使用单元测试
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')
```
这篇文章解释了所有,下面的片段对我有用
How to Mock Environment Variables in Python’s unittest
import os
from unittest import TestCase, mock
class SettingsTests(TestCase):
@classmethod
def setUpClass(cls):
cls.env_patcher = mock.patch.dict(os.environ, {"FROBNICATION_COLOUR": "ROUGE"})
cls.env_patcher.start()
super().setUpClass()
@classmethod
def tearDownClass(cls):
super().tearDownClass()
cls.env_patcher.stop()
def setUp(self):
super().setUp()
self.assertEqual(os.environ["FROBNICATION_COLOUR"], "ROUGE")
def test_frobnication_colour(self):
self.assertEqual(os.environ["FROBNICATION_COLOUR"], "ROUGE")
一路指点Mock Environment Variables in Python’s unittest
https://adamj.eu/tech/2020/10/13/how-to-mock-environment-variables-with-pythons-unittest/
我希望能够在我的 Django 应用程序中设置环境变量,以便能够进行测试 运行。例如,我的观点依赖于几个 API 键。
有一些方法可以 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
中,它没有办法(据我所知)来设置它。
我该如何解决这个问题?
我使用 py.test
作为我的测试运行器,它允许您创建一个 pytest.ini
文件,您可以在其中指定要在 运行 测试时使用的特定设置文件。
在此处查看相关文档:
http://pytest-django.readthedocs.org/en/latest/configuring_django.html#pytest-ini-settings
我一般推荐 py.test 作为测试运行器,因为它支持不同类型的测试 类 甚至是简单的功能,并且设置 fixture 或其他运行之前的代码非常容易并经过测试。
正如@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
这会在上下文对象 with
语句期间正确设置环境变量。
老问题,但它出现在 Google 搜索中,现有答案都不合适。如果您使用的是 pytest,环境变量可以是 set/restored 使用 pytest's monkeypatching functionality.
test.support.EnvironmentVarGuard
是一个内部的 API,可能会随着版本的改变而改变(向后不兼容)。 事实上,整个 test
包仅供内部使用。 在测试包文档页面上明确说明它用于核心库的内部测试,而不是 public API。 (见下面的链接)
您应该在 python 的标准库 unittest.mock
中使用 patch.dict()
。它可以用作上下文管理器、装饰器或 class 装饰器。请参阅下面从官方 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
软件包说明
如果您像这样在 Django 的 settings.py
文件中加载环境变量:
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):
最初,我的环境变量 PARTNER_CODE
设置为 wow
。
我可以使用以下方法更改环境变量:
from test.support import EnvironmentVarGuard
with EnvironmentVarGuard() as env:
env['PARTNER_CODE'] = 'sos'
现在我的环境变量 PARTNER_CODE
显示 sos
。
使用 EnvironmentVarGuard
不是一个好的解决方案,因为它在某些环境中失败而在其他环境中有效。请参阅下面的示例。
erewok 提出的更好的解决方案需要使用 python3 中的 unittest.mock
。
假设使用单元测试
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')
```
这篇文章解释了所有,下面的片段对我有用 How to Mock Environment Variables in Python’s unittest
import os
from unittest import TestCase, mock
class SettingsTests(TestCase):
@classmethod
def setUpClass(cls):
cls.env_patcher = mock.patch.dict(os.environ, {"FROBNICATION_COLOUR": "ROUGE"})
cls.env_patcher.start()
super().setUpClass()
@classmethod
def tearDownClass(cls):
super().tearDownClass()
cls.env_patcher.stop()
def setUp(self):
super().setUp()
self.assertEqual(os.environ["FROBNICATION_COLOUR"], "ROUGE")
def test_frobnication_colour(self):
self.assertEqual(os.environ["FROBNICATION_COLOUR"], "ROUGE")
一路指点Mock Environment Variables in Python’s unittest
https://adamj.eu/tech/2020/10/13/how-to-mock-environment-variables-with-pythons-unittest/