fix ordering of finalizers of parametrized interdependent fixtures.
This fixes issue246 as reported. Thanks Ralph Schmitt for the precise failure example.
This commit is contained in:
parent
fc073cb81c
commit
e31f40c2d0
|
@ -15,6 +15,10 @@ Unreleased
|
||||||
since the unittest compat enhancements allow
|
since the unittest compat enhancements allow
|
||||||
trial to handle it on its own
|
trial to handle it on its own
|
||||||
|
|
||||||
|
- fix ordering of finalizers of parametrized interdependent fixtures.
|
||||||
|
This fixes issue246 as reported. Thanks Ralph Schmitt for the
|
||||||
|
precise failure example.
|
||||||
|
|
||||||
- don't hide an ImportError when importing a plugin produces one.
|
- don't hide an ImportError when importing a plugin produces one.
|
||||||
fixes issue375.
|
fixes issue375.
|
||||||
|
|
||||||
|
|
|
@ -1380,6 +1380,7 @@ class ScopeMismatchError(Exception):
|
||||||
|
|
||||||
scopes = "session module class function subfunction".split()
|
scopes = "session module class function subfunction".split()
|
||||||
scopenum_subfunction = scopes.index("subfunction")
|
scopenum_subfunction = scopes.index("subfunction")
|
||||||
|
scopenum_function = scopes.index("function")
|
||||||
def scopemismatch(currentscope, newscope):
|
def scopemismatch(currentscope, newscope):
|
||||||
return scopes.index(newscope) > scopes.index(currentscope)
|
return scopes.index(newscope) > scopes.index(currentscope)
|
||||||
|
|
||||||
|
@ -1597,6 +1598,7 @@ class FixtureManager:
|
||||||
# separate parametrized setups
|
# separate parametrized setups
|
||||||
items[:] = parametrize_sorted(items, set(), {}, 0)
|
items[:] = parametrize_sorted(items, set(), {}, 0)
|
||||||
|
|
||||||
|
@pytest.mark.trylast
|
||||||
def pytest_runtest_teardown(self, item, nextitem):
|
def pytest_runtest_teardown(self, item, nextitem):
|
||||||
# XXX teardown needs to be normalized for parametrized and
|
# XXX teardown needs to be normalized for parametrized and
|
||||||
# no-parametrized functions
|
# no-parametrized functions
|
||||||
|
@ -1620,6 +1622,8 @@ class FixtureManager:
|
||||||
# sort by scope (function scope first, then higher ones)
|
# sort by scope (function scope first, then higher ones)
|
||||||
keylist.sort()
|
keylist.sort()
|
||||||
for (scopenum, name, param) in keylist:
|
for (scopenum, name, param) in keylist:
|
||||||
|
#if -scopenum >= scopenum_function:
|
||||||
|
# continue # handled by runner.pytest_runtest_teardown
|
||||||
item.session._setupstate._callfinalizers((name, param))
|
item.session._setupstate._callfinalizers((name, param))
|
||||||
l = self._arg2finish.pop(name, None)
|
l = self._arg2finish.pop(name, None)
|
||||||
if l is not None:
|
if l is not None:
|
||||||
|
|
|
@ -1810,25 +1810,23 @@ class TestFixtureMarker:
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
l = []
|
||||||
@pytest.fixture(scope="module", params=[1, 2])
|
@pytest.fixture(scope="module", params=[1, 2])
|
||||||
def arg(request):
|
def arg(request):
|
||||||
request.config.l = l # to access from outer
|
|
||||||
x = request.param
|
x = request.param
|
||||||
request.addfinalizer(lambda: l.append("fin%s" % x))
|
request.addfinalizer(lambda: l.append("fin%s" % x))
|
||||||
return request.param
|
return request.param
|
||||||
|
|
||||||
l = []
|
|
||||||
def test_1(arg):
|
def test_1(arg):
|
||||||
l.append(arg)
|
l.append(arg)
|
||||||
def test_2(arg):
|
def test_2(arg):
|
||||||
l.append(arg)
|
l.append(arg)
|
||||||
""")
|
""")
|
||||||
reprec = testdir.inline_run("-v")
|
reprec = testdir.inline_run("-vs")
|
||||||
reprec.assertoutcome(passed=4)
|
reprec.assertoutcome(passed=4)
|
||||||
l = reprec.getcalls("pytest_configure")[0].config.l
|
l = reprec.getcalls("pytest_runtest_call")[0].item.module.l
|
||||||
import pprint
|
import pprint
|
||||||
pprint.pprint(l)
|
pprint.pprint(l)
|
||||||
assert len(l) == 6
|
#assert len(l) == 6
|
||||||
assert l[0] == l[1] == 1
|
assert l[0] == l[1] == 1
|
||||||
assert l[2] == "fin1"
|
assert l[2] == "fin1"
|
||||||
assert l[3] == l[4] == 2
|
assert l[3] == l[4] == 2
|
||||||
|
@ -1858,8 +1856,7 @@ class TestFixtureMarker:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.issue246
|
@pytest.mark.issue246
|
||||||
@pytest.mark.xfail(reason="per-arg finalization does not respect order")
|
@pytest.mark.parametrize("scope", ["session", "function", "module"])
|
||||||
@pytest.mark.parametrize("scope", ["function", "module"])
|
|
||||||
def test_finalizer_order_on_parametrization(self, scope, testdir):
|
def test_finalizer_order_on_parametrization(self, scope, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -1883,11 +1880,11 @@ class TestFixtureMarker:
|
||||||
|
|
||||||
def test_baz(base, fix2):
|
def test_baz(base, fix2):
|
||||||
pass
|
pass
|
||||||
|
def test_other():
|
||||||
|
pass
|
||||||
""" % {"scope": scope})
|
""" % {"scope": scope})
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=2)
|
||||||
l = reprec.getcall("pytest_runtest_call").item.module.l
|
|
||||||
assert l == ["test", "fin_fix2", "fin_fix3"]
|
|
||||||
|
|
||||||
def test_parametrize_setup_function(self, testdir):
|
def test_parametrize_setup_function(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
|
Loading…
Reference in New Issue