[Python] Pytest fixture is changing the instance returned by another fixture

Discussão em 'Python' iniciado por Stack, Abril 5, 2025.

  1. Stack

    Stack Membro Participativo

    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

    Continue reading...

Compartilhe esta Página