Ensure all finalizations are run when one fails
Fixes issue287.
This commit is contained in:
parent
9b21d3f206
commit
72752165df
|
@ -1,6 +1,10 @@
|
|||
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
|
||||
since the unittest compat enhancements allow
|
||||
trial to handle it on its own
|
||||
|
|
|
@ -328,9 +328,17 @@ class SetupState(object):
|
|||
|
||||
def _callfinalizers(self, colitem):
|
||||
finalizers = self._finalizers.pop(colitem, None)
|
||||
exc = None
|
||||
while finalizers:
|
||||
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):
|
||||
self._callfinalizers(colitem)
|
||||
|
|
|
@ -43,6 +43,21 @@ class TestSetupState:
|
|||
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:
|
||||
def test_passfunction(self, testdir):
|
||||
|
|
Loading…
Reference in New Issue