Similar to this question: py.test: Pass a parameter to a fixture function, however, we want to also paramaterise inputs to the test.
For example (this is simplified version of what I want to do):
import pytest
def person_says(name, age):
return f"{name} is {age}"
@pytest.fixture
def add_surname(request):
surname = request.param
return f'Mike {surname}'
NAME1 = "Johnson"
AGE1 = "13"
OUTPUT1 = "Mike Johnson is 13"
NAME2 = "Liam"
AGE2 = "21"
OUTPUT2 = "Mike Liam is 21"
I want to pass something like this:
@pytest.mark.parametrize('add_surname,age,expected',
[[NAME1, AGE1, OUTPUT1],
[NAME2, AGE2, OUTPUT2]],
indirect=True)
def test_person_says(add_surname, age, expected):
name = add_surname
output = person_says(name, age)
assert expected == output
But that doesn't work, as it looks for the fixture age
, which doesn't exist.
Using multiple decorators does all 4 combinations.
@pytest.mark.parametrize('age,expected', [[AGE1, OUTPUT1], [AGE2, OUTPUT2]])
@pytest.mark.parametrize('add_surname', [NAME1, NAME2], indirect=True)
def test_person_says(add_surname, age, expected):
name = add_surname
output = person_says(name, age)
assert expected == output
Results:
Expected :Mike Liam is 21 Actual :Mike Johnson is 21 # FAIL
Expected :Mike Johnson is 13 Actual :Mike Johnson is 13 # Pass
Expected :Mike Johnson is 13 Actual :Mike Liam is 13 # FAIL
Expected :Mike Liam is 21 Actual :Mike Liam is 21 # Pass
What is the best way of doing it?