Closed
Description
Calling fixture finalizers in the correct order works by dependent fixtures registering their finalizer in their dependency (see python.FixtureDef.execute+10).
However, this only happens for fixtures explicitly requested in args, not for autouse or getfuncargvalue fixtures.
This code:
import pytest
@pytest.fixture(scope="session")
def global_dict():
return {}
@pytest.fixture(scope="session", autouse=True)
def add_1(global_dict):
global_dict[1] = "a"
print("add_1 setup", global_dict)
yield global_dict
print("add_1 teardown", global_dict)
del global_dict[1]
@pytest.fixture(scope="session")
def change_1_to_2(global_dict):
global_dict[2] = global_dict.pop(1)
print("change_1_to_2 setup", global_dict)
yield global_dict
print("change_1_to_2 teardown", global_dict)
global_dict[1] = global_dict.pop(2)
def test1(change_1_to_2):
assert change_1_to_2[2] == "a"
def test2(global_dict):
assert global_dict[2] == "a"
gives with py.test --capture=no test.py
:
============================= test session starts ==============================
platform linux2 -- Python 2.7.11, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: /home/amos/git/test_py, inifile:
collected 2 items
test.py add_1 setup {1: 'a'}
change_1_to_2 setup {2: 'a'}
..add_1 teardown {2: 'a'}
change_1_to_2 teardown {2: 'a'}
E
==================================== ERRORS ====================================
__________________________ ERROR at teardown of test2 __________________________
global_dict = {1: 'a'}
@pytest.yield_fixture(scope="session", autouse=True)
def add_1(global_dict):
global_dict[1] = "a"
print "add_1 setup", global_dict
yield global_dict
print "add_1 teardown", global_dict
> del global_dict[1]
E KeyError: 1
test.py:14: KeyError
====================== 2 passed, 1 error in 0.01 seconds =======================
as does this code:
import pytest
@pytest.fixture(scope="session")
def global_dict():
return {}
@pytest.yield_fixture(scope="session")
def add_1(global_dict):
global_dict[1] = "a"
print "add_1 setup", global_dict
yield global_dict
print "add_1 teardown", global_dict
del global_dict[1]
@pytest.yield_fixture(scope="session")
def change_1_to_2(request):
add_1 = request.getfuncargvalue("add_1")
add_1[2] = add_1.pop(1)
print "change_1_to_2 setup", add_1
yield add_1
print "change_1_to_2 teardown", add_1
add_1[1] = add_1.pop(2)
def test1(change_1_to_2):
assert change_1_to_2[2] == "a"
def test2(global_dict):
assert global_dict[2] == "a"