2017-08-28 34 views
0

我使用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) 

和一些测试:

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

def test_service_when_resource_broken(service): 
    assert service.status == "bad" 

我如何可以覆盖resource夹具,这样是这样的:

@pytest.fixture 
def broken_resource(cache): 
    return Resource(cache=cache, working=False) 

。 ..但仅限于test_service_when_resource_broken测试用例?我可以创建一个使用broken_resourcebroken_service,但实际情况是依赖链很长,我想重新使用所有的灯具,但在选择的测试中选择性地更改其中的一些。

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

@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" 

回答

2

您可以使用您的测试markers达到你期待什么。 基本上,你需要标记你需要不同行为的测试。在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" 
+0

完美。谢谢! –

+0

很高兴,它有帮助,请您将答案标记为已接受。 – Sanju