首页 > 解决方案 > 带有 pytest-mock 的会话范围

问题描述

我正在寻找有关如何使用 pytest-mock 插件的会话范围内的“会话模拟器”固定装置的示例。

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

def test_foo(session_mocker):
    session_mocker.patch('os.remove')
    etc...

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

标签: pythonpytestpytest-mock

解决方案


您在具有会话范围的夹具中使用它。放置它的最佳位置是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')

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

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


推荐阅读