fix issue226 - LIFO ordering for fixture-added teardowns
This commit is contained in:
parent
e15da7cbef
commit
b940ed11a0
|
@ -5,6 +5,7 @@ Changes between 2.3.3 and 2.3.4.dev
|
||||||
with autouse fixtures. If you need generative tests, use
|
with autouse fixtures. If you need generative tests, use
|
||||||
@pytest.mark.parametrize or pytest_generate_tests, see the
|
@pytest.mark.parametrize or pytest_generate_tests, see the
|
||||||
many examples at http://pytest.org/latest/example/parametrize.html
|
many examples at http://pytest.org/latest/example/parametrize.html
|
||||||
|
- fix issue226 - LIFO ordering for fixture teardowns
|
||||||
- fix issue224 - invocations with >256 char arguments now work
|
- fix issue224 - invocations with >256 char arguments now work
|
||||||
- fix issue91 - add/discuss package/directory level setups in example
|
- fix issue91 - add/discuss package/directory level setups in example
|
||||||
- allow to dynamically define markers via
|
- allow to dynamically define markers via
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#
|
#
|
||||||
__version__ = '2.3.4.dev4'
|
__version__ = '2.3.4.dev5'
|
||||||
|
|
|
@ -1224,6 +1224,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
if paramscopenum != scopenum_subfunction:
|
if paramscopenum != scopenum_subfunction:
|
||||||
scope = scopes[paramscopenum]
|
scope = scopes[paramscopenum]
|
||||||
|
|
||||||
|
# check if a higher-level scoped fixture accesses a lower level one
|
||||||
if scope is not None:
|
if scope is not None:
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
if scopemismatch(self.scope, scope):
|
if scopemismatch(self.scope, scope):
|
||||||
|
@ -1236,15 +1237,18 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
__tracebackhide__ = False
|
__tracebackhide__ = False
|
||||||
mp.setattr(self, "scope", scope)
|
mp.setattr(self, "scope", scope)
|
||||||
|
|
||||||
|
# route request.addfinalizer to fixturedef
|
||||||
|
mp.setattr(self, "addfinalizer", fixturedef.addfinalizer)
|
||||||
|
|
||||||
|
# perform the fixture call
|
||||||
|
val = fixturedef.execute(request=self)
|
||||||
|
|
||||||
# prepare finalization according to scope
|
# prepare finalization according to scope
|
||||||
# (XXX analyse exact finalizing mechanics / cleanup)
|
# (XXX analyse exact finalizing mechanics / cleanup)
|
||||||
self.session._setupstate.addfinalizer(fixturedef.finish, self.node)
|
self.session._setupstate.addfinalizer(fixturedef.finish, self.node)
|
||||||
self._fixturemanager.addargfinalizer(fixturedef.finish, argname)
|
self._fixturemanager.addargfinalizer(fixturedef.finish, argname)
|
||||||
for subargname in fixturedef.argnames: # XXX all deps?
|
for subargname in fixturedef.argnames: # XXX all deps?
|
||||||
self._fixturemanager.addargfinalizer(fixturedef.finish, subargname)
|
self._fixturemanager.addargfinalizer(fixturedef.finish, subargname)
|
||||||
mp.setattr(self, "addfinalizer", fixturedef.addfinalizer)
|
|
||||||
# finally perform the fixture call
|
|
||||||
val = fixturedef.execute(request=self)
|
|
||||||
mp.undo()
|
mp.undo()
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
@ -1503,6 +1507,8 @@ class FixtureManager:
|
||||||
items[:] = parametrize_sorted(items, set(), {}, 0)
|
items[:] = parametrize_sorted(items, set(), {}, 0)
|
||||||
|
|
||||||
def pytest_runtest_teardown(self, item, nextitem):
|
def pytest_runtest_teardown(self, item, nextitem):
|
||||||
|
# XXX teardown needs to be normalized for parametrized and
|
||||||
|
# no-parametrized functions
|
||||||
try:
|
try:
|
||||||
cs1 = item.callspec
|
cs1 = item.callspec
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -1524,7 +1530,7 @@ class FixtureManager:
|
||||||
keylist.sort()
|
keylist.sort()
|
||||||
for (scopenum, name, param) in keylist:
|
for (scopenum, name, param) in keylist:
|
||||||
item.session._setupstate._callfinalizers((name, param))
|
item.session._setupstate._callfinalizers((name, param))
|
||||||
l = self._arg2finish.get(name)
|
l = self._arg2finish.pop(name, None)
|
||||||
if l is not None:
|
if l is not None:
|
||||||
for fin in reversed(l):
|
for fin in reversed(l):
|
||||||
fin()
|
fin()
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -48,7 +48,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple powerful testing with Python',
|
description='py.test: simple powerful testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='2.3.4.dev4',
|
version='2.3.4.dev5',
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
|
@ -1105,7 +1105,7 @@ class TestAutouseManagement:
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=5)
|
reprec.assertoutcome(passed=5)
|
||||||
|
|
||||||
def test_setup_funcarg_order(self, testdir):
|
def test_ordering_autouse_before_explicit(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -1122,6 +1122,30 @@ class TestAutouseManagement:
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
@pytest.mark.issue226
|
||||||
|
@pytest.mark.parametrize("param1", ["", "params=[1]"])
|
||||||
|
@pytest.mark.parametrize("param2", ["", "params=[1]"])
|
||||||
|
def test_ordering_dependencies_torndown_first(self, testdir, param1, param2):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
l = []
|
||||||
|
@pytest.fixture(%(param1)s)
|
||||||
|
def arg1(request):
|
||||||
|
request.addfinalizer(lambda: l.append("fin1"))
|
||||||
|
l.append("new1")
|
||||||
|
@pytest.fixture(%(param2)s)
|
||||||
|
def arg2(request, arg1):
|
||||||
|
request.addfinalizer(lambda: l.append("fin2"))
|
||||||
|
l.append("new2")
|
||||||
|
|
||||||
|
def test_arg(arg2):
|
||||||
|
pass
|
||||||
|
def test_check():
|
||||||
|
assert l == ["new1", "new2", "fin2", "fin1"]
|
||||||
|
""" % locals())
|
||||||
|
reprec = testdir.inline_run("-s")
|
||||||
|
reprec.assertoutcome(passed=2)
|
||||||
|
|
||||||
class TestFixtureMarker:
|
class TestFixtureMarker:
|
||||||
def test_parametrize(self, testdir):
|
def test_parametrize(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
|
Loading…
Reference in New Issue