Pytest,如何针对灯具的值或无值进行测试?

时间:2019-10-16 08:50:23

标签: python integration-testing pytest

我有一个测试用例和一个夹具

@pytest.fixture
def user(test_client):
    return User.objects.first()


@pytest.mark.parametrize('content', ['nice post',])
def test_post(test_client, user, content):
    reponse = test_client.post(
        '/api/v1.0/posts', 
        json={
            'content': content,
            'author': user,
        },
        follow_redirects=True
    )

    assert reponse.status_code == 200

但是我除了要针对某些User对象进行测试之外,还要针对None进行测试(我希望测试对None失败)。我以为我可以做类似的事情:

@pytest.fixture(params=[True, False])
def User_or_null(test_client, request):
    if request.param:
        return User.objects.first()
    else:
        return None

但是我认为这不会允许我用pytest.mark.xfail标记测试用例的None值吗?有任何想法吗?

1 个答案:

答案 0 :(得分:2)

我看不到参数化user固定装置的问题。您可以通过pytest.param标记单独的参数,例如:

@pytest.fixture(params=[
    'testuser',
    # wrap None into pytest.param to treat it specially
    pytest.param(None, marks=pytest.mark.xfail)
])
def user(request):
    if request.param is None:
        return None
    return User.objects.filter(name=request.param).first()  # or whatever

但是,这意味着所有使用user固定装置的测试都将在None上进行xfail / xpass-这可能不是所有测试都想要的。如果要仅对选定的测试执行xfail操作,请使用间接参数化:

# user fixture is not parametrized now

@pytest.fixture
def user(request):
    if request.param is None:
        return None
    return User.objects.filter(name=request.param).first()

# instead, parametrizing is done from the test:

@pytest.mark.parametrize('content', ['nice post',])
@pytest.mark.parametrize('user', [
    'testuser',
    pytest.param(None, marks=pytest.mark.xfail
)], indirect=True)
def test_post(test_client, user, content):
    ...