I'm very baffled and a little concerned to discover the following behaviour where I have two tests and two fixtures.
import pytest
@pytest.fixture
def new_object():
return list()
@pytest.fixture
def a_string(new_object):
# Change this instance of the object
new_object.append(1)
return "a string"
def test_1(new_object):
assert len(new_object) == 0
def test_2(a_string, new_object):
assert len(new_object) == 0
The first test passes but the second one fails.
def test_2(a_string, new_object):
> assert len(new_object) == 0
E assert 1 == 0
E + where 1 = len([1])
tests/test_pytest_list.py:21: AssertionError
================================================ short test summary info =================================================
FAILED tests/test_pytest_list.py::test_2 - assert 1 == 0
============================================== 1 failed, 1 passed in 0.36s ===============================================
I expected fixtures to pass new instances of an object (unless specified otherwise), not the same object that some other fixture has modified.
According to the documentation about the scope of fixtures it says:
the default is to invoke once per test function
Does another fixture not qualify as a function?
UPDATE
Based on the comments I now understand the issue, although I still think it's a dangerous behaviour for a unit-testing tool.
Here's another invalid use of fixtures which a naive person like myself might not realize is wrong:
@pytest.fixture
def new_object():
"""I want to test instances of this class"""
return list()
@pytest.fixture
def case_1(new_object):
new_object.append(1)
return new_object
@pytest.fixture
def case_2(new_object):
new_object.append(2)
return new_object
def test_cases(case_1, case_2):
assert sum(case_1) + sum(case_2) == 3 # fails: assert (3 + 3) == 3
The fixture new_object
is invoked for each test as you clearly stated from the documentation.
The issue lies within your second fixture and the usage of the combination of both in your second test.
As pytest allows you to use fixtures more than once per test without affecting each other by using cached returns.
That means as the fixture a_word
uses the fixture new_object
the second time new_object
is encountered in your second test it uses the cached return value from the a_word
fixture call instead of giving you another empty list.