Reputation: 1634
I have a Python class like this:
class Foo:
def __init__(self, r=range(10)):
self.r = r
def bar(self):
# code
def hop(self):
# code
and I want to test it like this:
@pytest.fixture()
def foo():
return Foo()
def test_bar(foo):
# run tests
foo.r = range(20)
# run more tests
def test_hop(foo):
# run tests
I want the value of foo.r
in test_hop()
to be range(10)
, but instead it's range(20)
. Why is the value not getting reset?
I tried re-defining the fixture decorator as @pytest.fixture(scope='function')
(this is the default value, but I wanted to make sure that the fixture was getting 'torn down' at the end of each test). It made no difference to the result.
Upvotes: 0
Views: 904
Reputation: 1634
This is happening because range
s in Python are mutable. Thus, any changes made inside a test function will persist in subsequent test functions. Had the argument r
to __init__()
been something immutable, the fixture would have reset between tests as expected.
One way to get around this is to define r
as a tuple containing the limits of the range (tuples are immutable). Then, create the actual range
variable inside __init__()
, i.e.:
class Foo:
def __init__(self, r=tuple(0,10)):
self.r = range(r[0],r[1])
def bar(self):
# code
def hop(self):
# code
Now, the value of foo.r
in test_hop()
will be range(10)
.
Upvotes: 1