使用os.environ的pytest模块-如何正确测试?

spk*_*pky 5 python monkeypatching environment-variables pytest

目前,我正在编写一些Webapp,但是这次我想学习如何为它编写适当的测试(使用pytest):)

我经常看到的一种非常常见的模式是使用环境变量来更改默认配置。目前,我正在努力进行正确的测试。

我准备了一些演示:

./app
./app/conf.py
./conftest.py
./run.py
./tests
./tests/test_demo.py
Run Code Online (Sandbox Code Playgroud)

我的./app/conf.py样子是这样的:

from os import environ

DEMO = environ.get('DEMO', 'demo')
TEST = environ.get('TEST', 'test')
Run Code Online (Sandbox Code Playgroud)

通过启动./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)
Run Code Online (Sandbox Code Playgroud)

它打印出来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()
Run Code Online (Sandbox Code Playgroud)

如果我现在运行pytest,则test_conf_changed失败'demo' == 'tested demo'-> monkeypatch函数未修补环境。

如果我交换两个测试功能(因此test_conf_changed先运行),test_conf_defaults则将失败'tested demo' == 'demo'

我的解释是-首次conf导入时,它会保留在其初始设置中。

设置环境变量conf,如何告诉pytest完全重新导入每个测试函数?

我现在在那里呆了两天-慢慢地我怀疑测试是否值得解决-请证明我错了:)

spk*_*pky 7

感谢您的提示,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'
Run Code Online (Sandbox Code Playgroud)

谢谢。