Pytest 在运行时更改固定范围

hon*_*ute 7 fixtures pytest python-3.x

我在其中定义了通用装置,conftest.py这些装置在所有模块之间共享,并且作用范围为“功能”范围,如下所示:

测试.py

@pytest.fixture(scope="function")
def reset_state(services):
    # resets the state of the services
Run Code Online (Sandbox Code Playgroud)

我的测试目前将其称为如下,

测试模块一:

# change scope to session here
@pytest.mark.usefixtures("reset_state")
def test_something:
    # Test stuff using session-scoped fixtures.
Run Code Online (Sandbox Code Playgroud)

对于上述具体测试,我想将通用夹具的范围更改reset_state为“会话”。

有没有办法在运行时更改范围?

mis*_*ope 10

pytest5.2 版本开始,支持动态作用域。您可以提供自定义可调用对象作为固定范围,使其能够确定运行时的范围。

文档中的示例:

def determine_scope(fixture_name, config):
    if config.getoption("--keep-containers", None):
        return "session"
    return "function"


@pytest.fixture(scope=determine_scope)
def docker_container():
    yield spawn_container()
Run Code Online (Sandbox Code Playgroud)

请注意,它不允许您更改测试之间的运行时范围。如果是这种情况,当您希望session对所有测试使用作用域(除了少数改变夹具内部状态的测试之外)(因此您希望使用function作用域运行它们)时,有一个简单且非常明确的具有引用透明度的解决方法:

创建一种方法来创建测试主题,并使用两个不同范围的固定装置返回该方法的结果。

例子:

import pytest


def _make_fixture() -> object:
    """
    Returns:
        object: Some fixture for the test
    """
    return object()


@pytest.fixture(scope="function")
def function_scope_fixture() -> object:
    """
    Returns:
        object: Function scope use fixture
    """
    return _make_fixture()


@pytest.fixture(scope="session")
def session_scope_fixture() -> object:
    """
    Returns:
        object: Session scope use fixture
    """
    return _make_fixture()


def test_1(session_scope_fixture):
    """Test without mutation of the fixture"""
    ...


def test_2(function_scope_fixture):
    """Test mutating the internal state of the fixture"""
    ...
Run Code Online (Sandbox Code Playgroud)