* `PlaceHolder and ErrorHolder` now support being given result details.
(Robert Collins) * ``ErrorHolder`` is now just a function - all the logic is in ``PlaceHolder``. (Robert Collins)
This commit is contained in:
8
NEWS
8
NEWS
@@ -7,6 +7,14 @@ Changes and improvements to testtools_, grouped by release.
|
||||
NEXT
|
||||
~~~~
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
* ``PlaceHolder`` and ``ErrorHolder`` now support being given result details.
|
||||
(Robert Collins)
|
||||
|
||||
* ``ErrorHolder`` is now just a function - all the logic is in ``PlaceHolder``.
|
||||
(Robert Collins)
|
||||
|
||||
0.9.14
|
||||
~~~~~~
|
||||
|
||||
@@ -42,7 +42,10 @@ from testtools.matchers import (
|
||||
)
|
||||
from testtools.monkey import patch
|
||||
from testtools.runtest import RunTest
|
||||
from testtools.testresult import TestResult
|
||||
from testtools.testresult import (
|
||||
ExtendedToOriginalDecorator,
|
||||
TestResult,
|
||||
)
|
||||
|
||||
wraps = try_import('functools.wraps')
|
||||
|
||||
@@ -602,21 +605,30 @@ class PlaceHolder(object):
|
||||
particularly suitable for being added to TestResults.
|
||||
"""
|
||||
|
||||
def __init__(self, test_id, short_description=None):
|
||||
failureException = None
|
||||
|
||||
def __init__(self, test_id, short_description=None, details=None,
|
||||
outcome='addSuccess', error=None):
|
||||
"""Construct a `PlaceHolder`.
|
||||
|
||||
:param test_id: The id of the placeholder test.
|
||||
:param short_description: The short description of the place holder
|
||||
test. If not provided, the id will be used instead.
|
||||
:param details: Outcome details as accepted by addSuccess etc.
|
||||
:param outcome: The outcome to call. Defaults to 'addSuccess'.
|
||||
"""
|
||||
self._test_id = test_id
|
||||
self._short_description = short_description
|
||||
self._details = details or {}
|
||||
self._outcome = outcome
|
||||
if error is not None:
|
||||
self._details['traceback'] = content.TracebackContent(error, self)
|
||||
|
||||
def __call__(self, result=None):
|
||||
return self.run(result=result)
|
||||
|
||||
def __repr__(self):
|
||||
internal = [self._test_id]
|
||||
internal = [self._outcome, self._test_id, self._details]
|
||||
if self._short_description is not None:
|
||||
internal.append(self._short_description)
|
||||
return "<%s.%s(%s)>" % (
|
||||
@@ -636,11 +648,17 @@ class PlaceHolder(object):
|
||||
def id(self):
|
||||
return self._test_id
|
||||
|
||||
def run(self, result=None):
|
||||
def _result(self, result):
|
||||
if result is None:
|
||||
result = TestResult()
|
||||
return TestResult()
|
||||
else:
|
||||
return ExtendedToOriginalDecorator(result)
|
||||
|
||||
def run(self, result=None):
|
||||
result = self._result(result)
|
||||
result.startTest(self)
|
||||
result.addSuccess(self)
|
||||
outcome = getattr(result, self._outcome)
|
||||
outcome(self, details=self._details)
|
||||
result.stopTest(self)
|
||||
|
||||
def shortDescription(self):
|
||||
@@ -650,37 +668,18 @@ class PlaceHolder(object):
|
||||
return self._short_description
|
||||
|
||||
|
||||
class ErrorHolder(PlaceHolder):
|
||||
"""A placeholder test that will error out when run."""
|
||||
def ErrorHolder(test_id, error, short_description=None, details=None):
|
||||
"""Construct an `ErrorHolder`.
|
||||
|
||||
failureException = None
|
||||
|
||||
def __init__(self, test_id, error, short_description=None):
|
||||
"""Construct an `ErrorHolder`.
|
||||
|
||||
:param test_id: The id of the test.
|
||||
:param error: The exc info tuple that will be used as the test's error.
|
||||
:param short_description: An optional short description of the test.
|
||||
"""
|
||||
super(ErrorHolder, self).__init__(
|
||||
test_id, short_description=short_description)
|
||||
self._error = error
|
||||
|
||||
def __repr__(self):
|
||||
internal = [self._test_id, self._error]
|
||||
if self._short_description is not None:
|
||||
internal.append(self._short_description)
|
||||
return "<%s.%s(%s)>" % (
|
||||
self.__class__.__module__,
|
||||
self.__class__.__name__,
|
||||
", ".join(map(repr, internal)))
|
||||
|
||||
def run(self, result=None):
|
||||
if result is None:
|
||||
result = TestResult()
|
||||
result.startTest(self)
|
||||
result.addError(self, self._error)
|
||||
result.stopTest(self)
|
||||
:param test_id: The id of the test.
|
||||
:param error: The exc info tuple that will be used as the test's error.
|
||||
This is inserted into the details as 'traceback' - any existing key
|
||||
will be overridden.
|
||||
:param short_description: An optional short description of the test.
|
||||
:param details: Outcome details as accepted by addSuccess etc.
|
||||
"""
|
||||
return PlaceHolder(test_id, short_description=short_description,
|
||||
details=details, outcome='addError', error=error)
|
||||
|
||||
|
||||
# Python 2.4 did not know how to copy functions.
|
||||
|
||||
@@ -77,16 +77,21 @@ class TestPlaceHolder(TestCase):
|
||||
# repr(placeholder) shows you how the object was constructed.
|
||||
test = PlaceHolder("test id")
|
||||
self.assertEqual(
|
||||
"<testtools.testcase.PlaceHolder(%s)>" % repr(test.id()),
|
||||
repr(test))
|
||||
"<testtools.testcase.PlaceHolder('addSuccess', %s, {})>" % repr(
|
||||
test.id()), repr(test))
|
||||
|
||||
def test_repr_with_description(self):
|
||||
# repr(placeholder) shows you how the object was constructed.
|
||||
test = PlaceHolder("test id", "description")
|
||||
self.assertEqual(
|
||||
"<testtools.testcase.PlaceHolder(%r, %r)>" % (
|
||||
test.id(), test.shortDescription()),
|
||||
repr(test))
|
||||
"<testtools.testcase.PlaceHolder('addSuccess', %r, {}, %r)>" % (
|
||||
test.id(), test.shortDescription()), repr(test))
|
||||
|
||||
def test_repr_custom_outcome(self):
|
||||
test = PlaceHolder("test id", outcome='addSkip')
|
||||
self.assertEqual(
|
||||
"<testtools.testcase.PlaceHolder('addSkip', %r, {})>" % (
|
||||
test.id()), repr(test))
|
||||
|
||||
def test_counts_as_one_test(self):
|
||||
# A placeholder test counts as one test.
|
||||
@@ -107,6 +112,17 @@ class TestPlaceHolder(TestCase):
|
||||
[('startTest', test), ('addSuccess', test), ('stopTest', test)],
|
||||
log)
|
||||
|
||||
def test_supplies_details(self):
|
||||
details = {'quux':None}
|
||||
test = PlaceHolder('foo', details=details)
|
||||
result = ExtendedTestResult()
|
||||
test.run(result)
|
||||
self.assertEqual(
|
||||
[('startTest', test),
|
||||
('addSuccess', test, details),
|
||||
('stopTest', test)],
|
||||
result._events)
|
||||
|
||||
def test_call_is_run(self):
|
||||
# A PlaceHolder can be called, in which case it behaves like run.
|
||||
test = self.makePlaceHolder()
|
||||
@@ -127,6 +143,8 @@ class TestPlaceHolder(TestCase):
|
||||
|
||||
|
||||
class TestErrorHolder(TestCase):
|
||||
# Note that these tests exist because ErrorHolder exists - it could be
|
||||
# deprecated and dropped at this point.
|
||||
|
||||
run_test_with = FullStackRunTest
|
||||
|
||||
@@ -158,23 +176,6 @@ class TestErrorHolder(TestCase):
|
||||
test = ErrorHolder("test id", self.makeException(), "description")
|
||||
self.assertEqual("description", test.shortDescription())
|
||||
|
||||
def test_repr_just_id(self):
|
||||
# repr(placeholder) shows you how the object was constructed.
|
||||
error = self.makeException()
|
||||
test = ErrorHolder("test id", error)
|
||||
self.assertEqual(
|
||||
"<testtools.testcase.ErrorHolder(%r, %r)>" % (test.id(), error),
|
||||
repr(test))
|
||||
|
||||
def test_repr_with_description(self):
|
||||
# repr(placeholder) shows you how the object was constructed.
|
||||
error = self.makeException()
|
||||
test = ErrorHolder("test id", error, "description")
|
||||
self.assertEqual(
|
||||
"<testtools.testcase.ErrorHolder(%r, %r, %r)>" % (
|
||||
test.id(), error, test.shortDescription()),
|
||||
repr(test))
|
||||
|
||||
def test_counts_as_one_test(self):
|
||||
# A placeholder test counts as one test.
|
||||
test = self.makePlaceHolder()
|
||||
@@ -186,16 +187,30 @@ class TestErrorHolder(TestCase):
|
||||
self.assertEqual(test.id(), str(test))
|
||||
|
||||
def test_runs_as_error(self):
|
||||
# When run, a PlaceHolder test records a success.
|
||||
# When run, an ErrorHolder test records an error.
|
||||
error = self.makeException()
|
||||
test = self.makePlaceHolder(error=error)
|
||||
log = []
|
||||
test.run(LoggingResult(log))
|
||||
result = ExtendedTestResult()
|
||||
log = result._events
|
||||
test.run(result)
|
||||
self.assertEqual(
|
||||
[('startTest', test),
|
||||
('addError', test, error),
|
||||
('addError', test, test._details),
|
||||
('stopTest', test)], log)
|
||||
|
||||
def test_supplies_details(self):
|
||||
details = {'quux':None}
|
||||
error = self.makeException()
|
||||
test = ErrorHolder('foo', error, details=details)
|
||||
result = ExtendedTestResult()
|
||||
test.run(result)
|
||||
self.assertEqual(
|
||||
[('startTest', test),
|
||||
('addError', test, details),
|
||||
('stopTest', test)],
|
||||
result._events)
|
||||
self.assertTrue('traceback' in details)
|
||||
|
||||
def test_call_is_run(self):
|
||||
# A PlaceHolder can be called, in which case it behaves like run.
|
||||
test = self.makePlaceHolder()
|
||||
|
||||
Reference in New Issue
Block a user