在pytest中覆盖子夹具

Jim*_*art 1 python pytest

我正在使用带有一些复杂的依赖注入夹具的pytest。我的灯具在长链中使用其他灯具。我希望能够针对特定测试更改链中间的某些固定装置。

鉴于这些(简化的)装置:

@pytest.fixture
def cache():
    return Cache()

# Use cache fixture in a new fixture.
@pytest.fixture
def resource(cache):
    return Resource(cache=cache, working=True)

# Use resource fixture in a new fixture.
@pytest.fixture
def service(resource):
    return Service(resource=resource)
Run Code Online (Sandbox Code Playgroud)

和一些测试:

def test_service_when_resource_working(service):
    assert service.status == "good"

def test_service_when_resource_broken(service):
    assert service.status == "bad"
Run Code Online (Sandbox Code Playgroud)

如何覆盖resource灯具,使其像这样:

@pytest.fixture
def broken_resource(cache):
    return Resource(cache=cache, working=False)
Run Code Online (Sandbox Code Playgroud)

...但仅适用于test_service_when_resource_broken测试用例?我可以创建一个broken_serviceusing broken_resource,但是现实是依赖链很长,我想重用所有的固定装置,但是有选择地在中间为某些选定的测试更改它们。

我想做这样的事情(伪代码):

@pytest.override_fixture('resource', 'broken_resource')
def test_service_when_resource_broken(service):
    # service should have been instantiated with broken_resource instead of resource.
    assert service.status == "bad"
Run Code Online (Sandbox Code Playgroud)

San*_*nju 5

您可以在测试中使用标记来达到您的期望。基本上,您标记需要其他行为的测试。在fixture方法中,从请求的测试上下文和过程中查找该标记。

这是您的操作方法。

@pytest.fixture
def cache():
    return Cache()

# Use cache fixture in a new fixture.


@pytest.fixture
def resource(request, cache):
    working = True
    marker = request.node.get_marker("broken")
    if marker:
        working = False

    return Resource(cache=cache, working=working)


# Use resource fixture in a new fixture.
@pytest.fixture
def service(resource):
    return Service(resource=resource)


def test_service_when_resource_working(service):
    assert service.status == "good"


@pytest.mark.broken
def test_service_when_resource_broken(service):
    assert service.status == "bad"
Run Code Online (Sandbox Code Playgroud)