Reputation: 2636
I am trying to better understand how to thoroughly unit test using pytest
and came across a situation that I am not sure how to best approach. I found similar questions here on SO about parameterizing fixtures themselves but I don't think that is what I want to do here. But maybe I am not fully understanding fixtures themselves?
Here is some sample code:
class Person:
def __init__(self, fname: str, lname: str):
self.fname = fname
self.lname = lname
def upper_fullname(self):
return f'{self.fname} {self.lname}'.upper()
import pytest
@pytest.fixture(scope="module")
def fixture_mm(conf={"fname": "mickey", "lname": "mouse"}):
return Person(**conf)
@pytest.fixture(scope="module")
def fixture_bb(conf={"fname": "bugs", "lname": "bunny"}):
return Person(**conf)
@pytest.mark.parametrize(
'person, expected_result',
[(fixture_mm, "MICKEY MOUSE"), (fixture_bb, "BUGS BUNNY")])
def test_uppernames(person, expected_result):
assert person.upper_fullname() == expected_result
I would expect both of these tests to pass but instead I get an error message saying AttributeError: 'function' object has no attribute 'upper_fullname'
. What am I missing here?
Thanks.
Upvotes: 1
Views: 188
Reputation: 7930
You're getting an error because fixture_mm
is a function. You need to call a function to get a value (fixture_mm()
), but this is not going to work with fixtures.
But I don't think you even need fixtures here. You could make these into normal functions and use them like this:
def person_mm(conf={"fname": "mickey", "lname": "mouse"}):
return Person(**conf)
def person_bb(conf={"fname": "bugs", "lname": "bunny"}):
return Person(**conf)
@pytest.mark.parametrize(
'person, expected_result',
[(person_mm(), "MICKEY MOUSE"), (person_bb(), "BUGS BUNNY")])
def test_uppernames(person, expected_result):
assert person.upper_fullname() == expected_result
Caveat: since fixture parameters are evaluated at the module compile time, this might cause issues if the functions require some setup. On the other hand, if your functions are as simple as in this example, you could even save these objects as constants:
PERSON_MM = Person(fname="mickey", lname="mouse")
PERSON_BB = Person(fname="bugs", lname="bunny")
Upvotes: 2