【发布时间】:2015-06-18 12:36:59
【问题描述】:
目前我正在编写一些 Webapp,但这次我想学习如何为它编写适当的测试(使用 pytest):)
我经常看到的一个非常常见的模式是使用环境变量来更改默认配置。 目前我正在努力如何正确测试它。
我已经准备了一些演示:
./app
./app/conf.py
./conftest.py
./run.py
./tests
./tests/test_demo.py
我的./app/conf.py 看起来像这样:
from os import environ
DEMO = environ.get('DEMO', 'demo')
TEST = environ.get('TEST', 'test')
启动./run.py 表明设置确实可以更改:
from os import environ
environ['DEMO'] = 'not a demo'
environ['TEST'] = 'untested'
from app import conf
if __name__ == '__main__':
print(conf.DEMO)
print(conf.TEST)
它按预期打印出not a demo 和untested。伟大的。 (注意我在导入conf之前设置了环境变量)。
现在开始测试:./conftest.py 目前是空的,它只是帮助 pytest 定位 app 文件夹中的模块。
./tests/test_demo.py 包含以下内容:
def test_conf_defaults():
from app import conf
assert conf.DEMO == 'demo'
assert conf.TEST == 'test'
def test_conf_changed(monkeypatch):
monkeypatch.setenv('DEMO', 'tested demo')
monkeypatch.setenv('TEST', 'demo test')
from app import conf
assert conf.DEMO == 'tested demo'
assert conf.TEST == 'demo test'
monkeypatch.undo()
如果我现在运行 pytest,test_conf_changed 会失败并显示 'demo' == 'tested demo' -> monkeypatch 函数没有修补环境。
如果我交换两个测试函数(所以test_conf_changed 首先运行),test_conf_defaults 将失败并显示'tested demo' == 'demo'。
我的解释是——conf 第一次被导入时,它的初始设置一直停留在那里..
我如何告诉 pytest 完全重新导入conf 每个测试函数, 设置环境变量?
我现在被困在那里两天了-慢慢地我怀疑测试是否值得麻烦-请证明我错了:)
【问题讨论】:
-
我不确定你想要实现什么:如果你想运行测试,你运行
py.test,它会获取所有test_*.py文件并在其中运行测试。如果您想进行演示,您可以创建一个类似./demos/demo.py的文件并将其作为演示运行。我认为它们中的任何一个(当然不是 pytest)都不应该依赖于环境变量。 -
是的,当您导入
conf时,并且 conf 模块中的变量设置在全局命名空间中,它们会一直存在:仅在整个运行期间(python 会话)进行一次导入。如果你想继续阅读或设置 env.变量,在 conf.py 中创建一个函数,例如updateenv(),然后每次需要从其他函数中运行它以更新 env 变量。 -
我想要实现的目标:config.py 包含默认设置,但我想让它们可以更改。例如存储临时文件等的路径。
-
现在我想测试一下,如果分配工作正常 - 我写的演示只是用于 stackoverflow - 它与我的真实应用程序无关 - 它只是显示基本原理。
-
当然pytest应该独立于环境变量。我希望 pytest 设置一些变量(本地),然后测试我的代码(在 conf.py 中)是否使用这些变量正确运行...
标签: python environment-variables pytest monkeypatching