Add 'force_failure' feature to testtools.TestCase.

Change-Id: Idb8c8d0c837ab2cb6ec53c84d144c29b5d6da8ea
This commit is contained in:
Thomi Richards
2013-11-21 10:48:00 +13:00
committed by Robert Collins
parent ef233c98e7
commit 0f874b117b
6 changed files with 39 additions and 1 deletions

3
NEWS
View File

@@ -23,6 +23,9 @@ Improvements
exiting (2) when an import has failed rather than only signalling through the
test name. (Robert Collins, #1245672)
* Added ability for ``testtools.TestCase`` instances to force a test to
fail, even if no assertions failed. (Thomi Richards)
* Added ``testtools.content.StacktraceContent``, a content object that
automatically creates a ``StackLinesContent`` object containing the current
stack trace. (Thomi Richards)

View File

@@ -82,6 +82,15 @@ Test renaming
instance to one with a new name. This is helpful for implementing test
parameterization.
.. _force_failure:
Delayed Test Failure
--------------------
Setting the ``testtools.TestCase.force_failure`` instance variable to True will
cause ``testtools.RunTest`` to fail the test case after the test has finished.
This is useful when you want to cause a test to fail, but don't want to
prevent the remainder of the test code from being executed.
Test placeholders
=================

View File

@@ -1243,6 +1243,13 @@ Here are some tips for converting your Trial tests into testtools tests.
``AsynchronousDeferredRunTest`` does not. If you rely on this behavior, use
``AsynchronousDeferredRunTestForBrokenTwisted``.
force_failure
-------------
Setting the ``testtools.TestCase.force_failure`` instance variable to ``True``
will cause the test to be marked as a failure, but won't stop the test code
from running (see :ref:`force_failure`).
Test helpers
============

View File

@@ -135,6 +135,9 @@ class RunTest(object):
self._run_cleanups, self.result):
failed = True
finally:
if getattr(self.case, 'force_failure', None):
self._run_user(_raise_force_fail_error)
failed = True
if not failed:
self.result.addSuccess(self.case,
details=self.case.getDetails())
@@ -200,6 +203,10 @@ class RunTest(object):
raise e
def _raise_force_fail_error():
raise AssertionError("Forced Test Failure")
# Signal that this is part of the testing framework, and that code from this
# should not normally appear in tracebacks.
__unittest = True

View File

@@ -155,6 +155,8 @@ class TestCase(unittest.TestCase):
:ivar exception_handlers: Exceptions to catch from setUp, runTest and
tearDown. This list is able to be modified at any time and consists of
(exception_class, handler(case, result, exception_value)) pairs.
:ivar force_failure: Force testtools.RunTest to fail the test after the
test has completed.
:cvar run_tests_with: A factory to make the ``RunTest`` to run tests with.
Defaults to ``RunTest``. The factory is expected to take a test case
and an optional list of exception handlers.
@@ -924,7 +926,7 @@ class DecorateTestCaseResult(object):
def __getattr__(self, name):
return getattr(self.decorated, name)
def __delattr__(self, name):
delattr(self.decorated, name)

View File

@@ -569,6 +569,16 @@ class TestAssertions(TestCase):
self.assertFails(
expected, self.assertThat, matchee, matcher, verbose=True)
def test__force_failure_fails_test(self):
class Test(TestCase):
def test_foo(self):
self.force_failure = True
self.remaining_code_run = True
test = Test('test_foo')
result = test.run()
self.assertFalse(result.wasSuccessful())
self.assertTrue(test.remaining_code_run)
def get_error_string(self, e):
"""Get the string showing how 'e' would be formatted in test output.