def test_fixture_values_leak(pytester: Pytester) -> None:
    """Ensure that fixture objects are properly destroyed by the garbage collector at the end of their expected
    life-times (#2981).
    """
    pytester.makepyfile(
        """
        import dataclasses
        import gc
        import pytest
        import weakref

        @dataclasses.dataclass
        class SomeObj:
            name: str

        fix_of_test1_ref = None
        session_ref = None

        @pytest.fixture(scope='session')
        def session_fix():
            global session_ref
            obj = SomeObj(name='session-fixture')
            session_ref = weakref.ref(obj)
            return obj

        @pytest.fixture
        def fix(session_fix):
            global fix_of_test1_ref
            obj = SomeObj(name='local-fixture')
            fix_of_test1_ref = weakref.ref(obj)
            return obj

        def test1(fix):
            assert fix_of_test1_ref() is fix

        def test2():
            gc.collect()
            # fixture "fix" created during test1 must have been destroyed by now
            assert fix_of_test1_ref() is None
    """
    )
    # Running on subprocess does not activate the HookRecorder
    # which holds itself a reference to objects in case of the
    # pytest_assert_reprcompare hook
    result = pytester.runpytest_subprocess()
    result.stdout.fnmatch_lines(["* 2 passed *"])
Ensure that fixture objects are properly destroyed by the garbage collector at the end of their expected
    life-times (#2981).
    
testing/acceptance_test.py