I have comfortably been using @pytest.mark.parametrize()
in many tests now. I have not, however, succeeded in combining it with @pytest.fixture()
and I cannot find a question answering this issue.
This example applies @pytest.fixture()
succesfully (copied from another question that I cannot find anymore):
import pytest
def foo(data, key):
return data[key]
@pytest.fixture()
def dict_used_by_many_tests():
return {"name": "Dionysia", "age": 28, "location": "Athens"}
def test_foo_one(dict_used_by_many_tests):
actual = foo(dict_used_by_many_tests, "name")
expected = "Dionysia"
assert actual == expected
Now, in practice I want to use @pytest.mark.parametrize()
.
@pytest.fixture()
def dict_used_by_many_tests():
return {"name": "Dionysia", "age": 28, "location": "Athens"}
@pytest.mark.parametrize(
"dict_used_by_many_tests",
[
(dict_used_by_many_tests),
],
)
def test_foo_one(dict_used_by_many_tests):
actual = foo(dict_used_by_many_tests, "name")
expected = "Dionysia"
assert actual == expected
This results in the error: TypeError: 'function' object is not subscriptable
.
I tried calling dict_used_by_many_tests()
to work with its return value instead of the function object. This resulted in a Fixtures are not meant to be called directly
error, however.
One method is request.getfixturevalue
:
import pytest
@pytest.fixture()
def dict_used_by_many_tests():
return {
"name": "Dionysia",
"age": 28,
"location": "Athens",
}
@pytest.fixture()
def dict_used_by_some_tests():
return {
"name": "Medusa, maybe?",
"age": 2 << 32,
"location": "Underworld?",
}
@pytest.mark.parametrize(
"fixture_name",
[
"dict_used_by_many_tests",
"dict_used_by_some_tests",
],
)
def test_foo_one(request, fixture_name):
d = request.getfixturevalue(fixture_name)
# ...
Another is indirect parametrization:
import pytest
@pytest.fixture()
def character_dict(request):
if request.param == 1:
return {"name": "Dionysia", "age": 28, "location": "Athens"}
elif request.param == 2:
return {"name": "Medusa", "age": 2 << 32, "location": "Underworld"}
raise NotImplementedError(f"No such dict: {request.param!r}")
@pytest.mark.parametrize(
"character_dict",
[1, 2],
indirect=True,
)
def test_foo_one(character_dict):
assert isinstance(character_dict, dict)