Become compatible with newer Fixtures _setUp() API.
Previously, when gathering details caused by a setUp failure, a traceback occurred if the fixture used the newer _setUp(). This also had the side effect of not clearing up fixtures properly. Change-Id: I9d138e8d559e176867c6e3f4b89f784cf4d29f05 Fixes: https://bugs.launchpad.net/testtools/+bug/1469759
This commit is contained in:
parent
cd286b23f2
commit
11e50d3fc2
1
LICENSE
1
LICENSE
|
@ -19,6 +19,7 @@ The testtools authors are:
|
|||
* Vincent Ladeuil
|
||||
* Nikola Đipanov
|
||||
* Tristan Seligmann
|
||||
* Julian Edwards
|
||||
|
||||
and are collectively referred to as "testtools developers".
|
||||
|
||||
|
|
4
NEWS
4
NEWS
|
@ -21,6 +21,10 @@ Improvements
|
|||
report the lack of result as a test error. This ought to make weird
|
||||
concurrency interaction bugs easier to understand. (Jonathan Lange)
|
||||
|
||||
* Previously, when gathering details caused by a setUp() failure,
|
||||
a traceback occurred if the fixture used the newer _setUp().
|
||||
This had the side effect of not clearing up fixtures nor gathering details
|
||||
properly. This is now fixed. (Julian Edwards, #1469759)
|
||||
|
||||
2.0.0
|
||||
~~~~~
|
||||
|
|
|
@ -26,6 +26,7 @@ from extras import (
|
|||
try_import,
|
||||
try_imports,
|
||||
)
|
||||
fixtures = try_import('fixtures')
|
||||
# To let setup.py work, make this a conditional import.
|
||||
unittest = try_imports(['unittest2', 'unittest'])
|
||||
|
||||
|
@ -49,7 +50,10 @@ from testtools.matchers import (
|
|||
)
|
||||
from testtools.matchers._basic import _FlippedEquals
|
||||
from testtools.monkey import patch
|
||||
from testtools.runtest import RunTest
|
||||
from testtools.runtest import (
|
||||
MultipleExceptions,
|
||||
RunTest,
|
||||
)
|
||||
from testtools.testresult import (
|
||||
ExtendedToOriginalDecorator,
|
||||
TestResult,
|
||||
|
@ -680,10 +684,22 @@ class TestCase(unittest.TestCase):
|
|||
"""
|
||||
try:
|
||||
fixture.setUp()
|
||||
except MultipleExceptions as e:
|
||||
if (fixtures is not None and
|
||||
e.args[-1][0] is fixtures.fixture.SetupError):
|
||||
gather_details(e.args[-1][1].args[0], self.getDetails())
|
||||
raise
|
||||
except:
|
||||
exc_info = sys.exc_info()
|
||||
try:
|
||||
gather_details(fixture.getDetails(), self.getDetails())
|
||||
# fixture._details is not available if using the newer
|
||||
# _setUp() API in Fixtures because it already cleaned up
|
||||
# the fixture. Ideally this whole try/except is not
|
||||
# really needed any more, however, we keep this code to
|
||||
# remain compatible with the older setUp().
|
||||
if (safe_hasattr(fixture, '_details') and
|
||||
fixture._details is not None):
|
||||
gather_details(fixture.getDetails(), self.getDetails())
|
||||
except:
|
||||
# Report the setUp exception, then raise the error during
|
||||
# gather_details.
|
||||
|
|
|
@ -10,7 +10,10 @@ from testtools import (
|
|||
content_type,
|
||||
)
|
||||
from testtools.compat import _b, _u
|
||||
from testtools.matchers import Contains
|
||||
from testtools.matchers import (
|
||||
Contains,
|
||||
Equals,
|
||||
)
|
||||
from testtools.testresult.doubles import (
|
||||
ExtendedTestResult,
|
||||
)
|
||||
|
@ -18,7 +21,6 @@ from testtools.testresult.doubles import (
|
|||
fixtures = try_import('fixtures')
|
||||
LoggingFixture = try_import('fixtures.tests.helpers.LoggingFixture')
|
||||
|
||||
|
||||
class TestFixtureSupport(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -113,6 +115,40 @@ class TestFixtureSupport(TestCase):
|
|||
self.assertEqual(['content', 'traceback'], sorted(details))
|
||||
self.assertEqual('foobar', ''.join(details['content'].iter_text()))
|
||||
|
||||
def test_useFixture_details_captured_from__setUp(self):
|
||||
# Newer Fixtures deprecates setUp() in favour of _setUp().
|
||||
# https://bugs.launchpad.net/testtools/+bug/1469759 reports that
|
||||
# this is broken when gathering details from a broken _setUp().
|
||||
class BrokenFixture(fixtures.Fixture):
|
||||
def _setUp(self):
|
||||
fixtures.Fixture._setUp(self)
|
||||
self.addDetail('broken', content.text_content("foobar"))
|
||||
raise Exception("_setUp broke")
|
||||
fixture = BrokenFixture()
|
||||
class SimpleTest(TestCase):
|
||||
def test_foo(self):
|
||||
self.addDetail('foo_content', content.text_content("foo ok"))
|
||||
self.useFixture(fixture)
|
||||
result = ExtendedTestResult()
|
||||
SimpleTest('test_foo').run(result)
|
||||
self.assertEqual('addError', result._events[-2][0])
|
||||
details = result._events[-2][2]
|
||||
self.assertEqual(
|
||||
['broken', 'foo_content', 'traceback', 'traceback-1'],
|
||||
sorted(details))
|
||||
self.expectThat(
|
||||
''.join(details['broken'].iter_text()),
|
||||
Equals('foobar'))
|
||||
self.expectThat(
|
||||
''.join(details['foo_content'].iter_text()),
|
||||
Equals('foo ok'))
|
||||
self.expectThat(
|
||||
''.join(details['traceback'].iter_text()),
|
||||
Contains('_setUp broke'))
|
||||
self.expectThat(
|
||||
''.join(details['traceback-1'].iter_text()),
|
||||
Contains('foobar'))
|
||||
|
||||
def test_useFixture_original_exception_raised_if_gather_details_fails(self):
|
||||
# In bug #1368440 it was reported that when a fixture fails setUp
|
||||
# and gather_details errors on it, then the original exception that
|
||||
|
|
Loading…
Reference in New Issue