pytest-mock 的会话范围

Gad*_*s34 6 python pytest pytest-mock

我正在寻找如何使用 pytest-mock 插件的会话范围的“session-mocker”装置的示例。

如何修改文档提供的示例以在特定测试中使用它是相当清楚的:

def test_foo(session_mocker):
    session_mocker.patch('os.remove')
    etc...
Run Code Online (Sandbox Code Playgroud)

但我对这个全局装置应该在哪里以及如何初始化感到困惑。例如,假设我想为所有测试模拟“os.remove”。我是否在 confftest.py 中进行了设置?如果是,我该怎么做?

Dun*_*nes 7

您可以在具有会话范围的固定装置中使用它。放置它的最佳位置是conftest.py。这主要是为了让其他程序员清楚地知道这个装置的存在以及它可能在做什么。这很重要,因为这个装置会影响其他测试,而这些测试可能不一定知道这个装置,甚至不需要它。

我不建议在会话期间嘲笑某些内容。测试、类甚至模块,是的。但不是会议。

例如,以下测试test_normal通过或失败取决于是否test_mocked在同一会话中运行。由于它们位于同一个“文件”中,因此更容易发现问题。但是这些测试可能位于不同的测试文件中,这些文件看起来不相关,但如果两个测试在同一会话中运行,则会出现问题。

import pytest

# could be in conftest.py
@pytest.fixture(scope='session')
def myfixture(session_mocker):
    session_mocker.patch('sys.mymock', create=True)

def test_mocked(myfixture):
    import sys
    assert hasattr(sys, 'mymock')

def test_normal():
    import sys
    assert not hasattr(sys, 'mymock')
Run Code Online (Sandbox Code Playgroud)

相反,只需创建一个适用于测试、类或模块的固定装置,并将其直接包含在测试文件中。这样,行为就包含在需要它的测试集中。创建模拟的成本很低,因此为每个测试重新创建模拟并不是什么大问题。它甚至可能是有益的,因为每次测试都会重置模拟。

为那些设置成本高昂、没有状态或测试不会更改其状态的事物保存会话装置(例如,用作模板来创建每个测试将针对其运行的新数据库的数据库)。