Ensure all finalizations are run when one fails
Fixes issue287.
This commit is contained in:
parent
9b21d3f206
commit
72752165df
|
@ -1,6 +1,10 @@
|
||||||
Unreleased
|
Unreleased
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
- fix issue287 by running all finalizers but saving the exception
|
||||||
|
from the last failing finalizer and re-raising it so teardown will
|
||||||
|
still have failed.
|
||||||
|
|
||||||
- fix issue384 by removing the trial support code
|
- fix issue384 by removing the trial support code
|
||||||
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
|
||||||
|
|
|
@ -328,9 +328,17 @@ class SetupState(object):
|
||||||
|
|
||||||
def _callfinalizers(self, colitem):
|
def _callfinalizers(self, colitem):
|
||||||
finalizers = self._finalizers.pop(colitem, None)
|
finalizers = self._finalizers.pop(colitem, None)
|
||||||
|
exc = None
|
||||||
while finalizers:
|
while finalizers:
|
||||||
fin = finalizers.pop()
|
fin = finalizers.pop()
|
||||||
fin()
|
try:
|
||||||
|
fin()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
exc = py.std.sys.exc_info()
|
||||||
|
if exc:
|
||||||
|
py.builtin._reraise(*exc)
|
||||||
|
|
||||||
def _teardown_with_finalization(self, colitem):
|
def _teardown_with_finalization(self, colitem):
|
||||||
self._callfinalizers(colitem)
|
self._callfinalizers(colitem)
|
||||||
|
|
|
@ -43,6 +43,21 @@ class TestSetupState:
|
||||||
pytest.raises(ValueError, lambda: ss.prepare(item))
|
pytest.raises(ValueError, lambda: ss.prepare(item))
|
||||||
pytest.raises(ValueError, lambda: ss.prepare(item))
|
pytest.raises(ValueError, lambda: ss.prepare(item))
|
||||||
|
|
||||||
|
def test_teardown_multiple_one_fails(self, testdir):
|
||||||
|
r = []
|
||||||
|
def fin1(): r.append('fin1')
|
||||||
|
def fin2(): raise Exception('oops')
|
||||||
|
def fin3(): r.append('fin3')
|
||||||
|
item = testdir.getitem("def test_func(): pass")
|
||||||
|
ss = runner.SetupState()
|
||||||
|
ss.addfinalizer(fin1, item)
|
||||||
|
ss.addfinalizer(fin2, item)
|
||||||
|
ss.addfinalizer(fin3, item)
|
||||||
|
with pytest.raises(Exception) as err:
|
||||||
|
ss._callfinalizers(item)
|
||||||
|
assert err.value.args == ('oops',)
|
||||||
|
assert r == ['fin3', 'fin1']
|
||||||
|
|
||||||
|
|
||||||
class BaseFunctionalTests:
|
class BaseFunctionalTests:
|
||||||
def test_passfunction(self, testdir):
|
def test_passfunction(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue