目前我正在写一些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
每个测试函数?
我现在被困在那里两天了 - 慢慢地我怀疑测试是否值得麻烦 - 请证明我错了:)
答案 0 :(得分:6)
感谢提示,Evert(conf模块中的变量设置在全局命名空间内,它们坚持) - 我想我现在已经知道了。
要测试我的代码,我必须在设置环境变量后显式重新导入conf
。将./tests/test_demo.py
中的代码更改为此可以解决问题:
from importlib import reload
from app import conf
def test_conf_changed(monkeypatch):
monkeypatch.setenv('DEMO', 'tested demo')
monkeypatch.setenv('TEST', 'demo test')
reload(conf)
assert conf.DEMO == 'tested demo'
assert conf.TEST == 'demo test'
def test_conf_defaults():
reload(conf)
assert conf.DEMO == 'demo'
assert conf.TEST == 'test'
谢谢。