Pytest,如何针对夹具的值或 None 进行测试?
Pytest, How to do test against either fixture's value or None?
我有一个 test-case 和一个 fixture:
@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
值吗?有什么想法吗?
我没有发现参数化 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 - 这可能不是您想要的所有测试。如果你只想让选定的测试失败,请使用间接参数化:
# 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):
...
我有一个 test-case 和一个 fixture:
@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
值吗?有什么想法吗?
我没有发现参数化 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 - 这可能不是您想要的所有测试。如果你只想让选定的测试失败,请使用间接参数化:
# 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):
...