pytest:在各个文件之间重置mock对象

3

编辑:非常感谢任何测试建议,但我特别想知道是否有pytest可以强制实现隔离,而不是依赖于我自己始终记得清理模拟。

pytest是否支持在单个Python文件之间“重置”进程状态,或以其他方式将测试文件彼此隔离?

我们的CI过去会像这样调用单个文件上的pytest:

pytest file1.py
pytest file2.py
...

现在它会一次性为所有文件调用pytest,如下所示:
pytest file1.py file2.py ...

当一些测试文件(例如file1.py)执行模块级别的mock时,我们遇到了问题。例如(简化):

def setup_module():
    patch("path.to.some.module.var", Mock()).start()

(没有相应的teardown_module。)

当pytest逐个文件运行时,这样做很好。但是当它运行多个文件时,先前执行的测试代码所做的任何模拟都会持续到后续的测试代码中。是否有任何方法在文件之间“重置”此状态?例如,pytest是否支持一种调用每个文件测试的分离进程的方法?(查看了pytest文档,但没有找到类似的内容。)

目前,我们正在添加teardown_module()函数,该函数调用patch.stopall(),但是让pytest隐式地将我们的测试文件相互隔离会更好。

1个回答

5
这样做的标准方式可能是使用上下文管理器作为装置,而不是使用设置/拆卸构造函数:
@pytest.fixture(scope="module", autouse=True)
def patch_var():
    with mock.patch("path.to.some.module.var"):
        yield

这将在测试超出模块范围后结束修补程序。

它与不太方便的方式具有相同的效果:

@pytest.fixture(scope="module", autouse=True)
def patch_var():
    patcher = mock.patch("path.to.some.module.var")
    patcher.start()
    yield
    patcher.stop()

请注意,如果您在构造的补丁程序对象上使用start,则需要自行停止打补丁。使用上下文管理器或打补丁装饰器(如果应用于单个测试)始终更安全。
更新: 据我所知,如果在同一次测试运行中执行,无法无条件地彻底隔离测试模块之间的关系,这就是fixture scopes概念的作用。
夹具总是应该带有自动清理代码。对于打补丁,您使用上下文管理器(如上所示),它会为您进行清理,其他事情您必须在yield之后自己清理。 如果您想在整个测试过程中进行全局更改,则使用会话范围的夹具。 如果要隔离测试模块,则使用模块范围的夹具,对于测试类或单个测试隔离,则使用类或函数范围的夹具。

谢谢,这很有帮助。+1。但是我刚刚编辑了问题,以使其更清楚,我正在寻找一种方法让pytest将文件彼此隔离,而不管每个文件内部发生了什么。 - undefined
我觉得我明白你的意思,但是按照你想要的方式是不可能的。我更新了答案以澄清这一点。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接