"Hook method for setting up the test fixture before exercising it."
"Hook method for deconstructing the test fixture after testing it."
"Hook method for setting up class fixture before running tests in the class."
"Hook method for deconstructing the class fixture after running all tests in the class."
def countTestCases(self):
def defaultTestResult(self):
return result.TestResult()
def shortDescription(self):
"""Returns a one-line description of the test, or None if no
description has been provided.
The default implementation of this method returns the first line of
the specified test method's docstring.
doc = self._testMethodDoc
return doc.strip().split("\n")[0].strip() if doc else None
return "%s.%s" % (strclass(self.__class__), self._testMethodName)
if type(self) is not type(other):
return self._testMethodName == other._testMethodName
return hash((type(self), self._testMethodName))
return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
return "<%s testMethod=%s>" % \
(strclass(self.__class__), self._testMethodName)
def _addSkip(self, result, test_case, reason):
addSkip = getattr(result, 'addSkip', None)
addSkip(test_case, reason)
warnings.warn("TestResult has no addSkip method, skips not reported",
result.addSuccess(test_case)
@contextlib.contextmanager
def subTest(self, msg=_subtest_msg_sentinel, **params):
"""Return a context manager that will return the enclosed block
of code in a subtest identified by the optional message and
keyword parameters. A failure in the subtest marks the test
case as failed but resumes execution at the end of the enclosed
block, allowing further test code to be executed.
if self._outcome is None or not self._outcome.result_supports_subtests:
params_map = _OrderedChainMap(params)
params_map = parent.params.new_child(params)
self._subtest = _SubTest(self, msg, params_map)
with self._outcome.testPartExecutor(self._subtest, isTest=True):
if not self._outcome.success:
result = self._outcome.result
if result is not None and result.failfast:
elif self._outcome.expectedFailure:
# If the test is expecting a failure, we really want to
# stop now and register the expected failure.
def _feedErrorsToResult(self, result, errors):
for test, exc_info in errors:
if isinstance(test, _SubTest):
result.addSubTest(test.test_case, test, exc_info)
elif exc_info is not None:
if issubclass(exc_info[0], self.failureException):
result.addFailure(test, exc_info)
result.addError(test, exc_info)
def _addExpectedFailure(self, result, exc_info):
addExpectedFailure = result.addExpectedFailure
warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
addExpectedFailure(self, exc_info)
def _addUnexpectedSuccess(self, result):
addUnexpectedSuccess = result.addUnexpectedSuccess
warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
# We need to pass an actual exception and traceback to addFailure,
# otherwise the legacy result can choke.
raise _UnexpectedSuccess from None
except _UnexpectedSuccess:
result.addFailure(self, sys.exc_info())
addUnexpectedSuccess(self)
def _callTestMethod(self, method):
def _callCleanup(self, function, /, *args, **kwargs):
function(*args, **kwargs)
def run(self, result=None):
result = self.defaultTestResult()
startTestRun = getattr(result, 'startTestRun', None)
if startTestRun is not None:
testMethod = getattr(self, self._testMethodName)
if (getattr(self.__class__, "__unittest_skip__", False) or
getattr(testMethod, "__unittest_skip__", False)):
# If the class or method was skipped.
skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
or getattr(testMethod, '__unittest_skip_why__', ''))
self._addSkip(result, self, skip_why)
expecting_failure_method = getattr(testMethod,
"__unittest_expecting_failure__", False)
expecting_failure_class = getattr(self,
"__unittest_expecting_failure__", False)
expecting_failure = expecting_failure_class or expecting_failure_method
outcome = _Outcome(result)
with outcome.testPartExecutor(self):
outcome.expecting_failure = expecting_failure
with outcome.testPartExecutor(self, isTest=True):
self._callTestMethod(testMethod)
outcome.expecting_failure = False
with outcome.testPartExecutor(self):
for test, reason in outcome.skipped:
self._addSkip(result, test, reason)
self._feedErrorsToResult(result, outcome.errors)
if outcome.expectedFailure:
self._addExpectedFailure(result, outcome.expectedFailure)
self._addUnexpectedSuccess(result)
stopTestRun = getattr(result, 'stopTestRun', None)
if stopTestRun is not None:
# explicitly break reference cycles:
# outcome.errors -> frame -> outcome -> outcome.errors
# outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
outcome.expectedFailure = None
# clear the outcome, no more needed
"""Execute all cleanup functions. Normally called for you after
outcome = self._outcome or _Outcome()
function, args, kwargs = self._cleanups.pop()
with outcome.testPartExecutor(self):
self._callCleanup(function, *args, **kwargs)
# return this for backwards compatibility
# even though we no longer use it internally
def doClassCleanups(cls):
"""Execute all class cleanup functions. Normally called for you after
cls.tearDown_exceptions = []
while cls._class_cleanups:
function, args, kwargs = cls._class_cleanups.pop()
function(*args, **kwargs)
cls.tearDown_exceptions.append(sys.exc_info())
def __call__(self, *args, **kwds):
return self.run(*args, **kwds)
"""Run the test without collecting errors in a TestResult"""
getattr(self, self._testMethodName)()
function, args, kwargs = self._cleanups.pop(-1)
function(*args, **kwargs)
def skipTest(self, reason):
def fail(self, msg=None):
"""Fail immediately, with the given message."""
raise self.failureException(msg)
def assertFalse(self, expr, msg=None):
"""Check that the expression is false."""
msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
raise self.failureException(msg)
def assertTrue(self, expr, msg=None):
"""Check that the expression is true."""
msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
raise self.failureException(msg)
def _formatMessage(self, msg, standardMsg):
"""Honour the longMessage attribute when generating failure messages.
If longMessage is False this means:
* Use only an explicit message if it is provided
* Otherwise use the standard message for the assert
* Use the standard message
* If an explicit message is provided, plus ' : ' and the explicit message
return msg or standardMsg
# don't switch to '{}' formatting in Python 2.X
# it changes the way unicode input is handled
return '%s : %s' % (standardMsg, msg)
except UnicodeDecodeError:
return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
def assertRaises(self, expected_exception, *args, **kwargs):
"""Fail unless an exception of class expected_exception is raised
by the callable when invoked with specified positional and
keyword arguments. If a different type of exception is
raised, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
If called with the callable and arguments omitted, will return a
context object used like this::
with self.assertRaises(SomeException):
An optional keyword argument 'msg' can be provided when assertRaises
is used as a context object.
The context manager keeps a reference to the exception as
the 'exception' attribute. This allows you to inspect the
exception after the assertion::
with self.assertRaises(SomeException) as cm:
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
context = _AssertRaisesContext(expected_exception, self)
return context.handle('assertRaises', args, kwargs)
# bpo-23890: manually break a reference cycle
def assertWarns(self, expected_warning, *args, **kwargs):
"""Fail unless a warning of class warnClass is triggered
by the callable when invoked with specified positional and
keyword arguments. If a different type of warning is
triggered, it will not be handled: depending on the other
warning filtering rules in effect, it might be silenced, printed
out, or raised as an exception.
If called with the callable and arguments omitted, will return a
context object used like this::
with self.assertWarns(SomeWarning):
An optional keyword argument 'msg' can be provided when assertWarns
is used as a context object.
The context manager keeps a reference to the first matching
warning as the 'warning' attribute; similarly, the 'filename'
and 'lineno' attributes give you information about the line
of Python code from which the warning was triggered.
This allows you to inspect the warning after the assertion::
with self.assertWarns(SomeWarning) as cm:
self.assertEqual(the_warning.some_attribute, 147)
context = _AssertWarnsContext(expected_warning, self)
return context.handle('assertWarns', args, kwargs)
def assertLogs(self, logger=None, level=None):
"""Fail unless a log message of level *level* or higher is emitted
on *logger_name* or its children. If omitted, *level* defaults to
INFO and *logger* defaults to the root logger.
This method must be used as a context manager, and will yield
a recording object with two attributes: `output` and `records`.
At the end of the context manager, the `output` attribute will
be a list of the matching formatted log messages and the
`records` attribute will be a list of the corresponding LogRecord
with self.assertLogs('foo', level='INFO') as cm:
logging.getLogger('foo').info('first message')
logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
'ERROR:foo.bar:second message'])
return _AssertLogsContext(self, logger, level)
def _getAssertEqualityFunc(self, first, second):
"""Get a detailed comparison function for the types of the two args.
Returns: A callable accepting (first, second, msg=None) that will
raise a failure exception if first != second with a useful human
readable error message for those types.
# NOTE(gregory.p.smith): I considered isinstance(first, type(second))
# and vice versa. I opted for the conservative approach in case
# subclasses are not intended to be compared in detail to their super
# class instances using a type equality func. This means testing
# subtypes won't automagically use the detailed comparison. Callers
# should use their type specific assertSpamEqual method to compare
# subclasses if the detailed comparison is desired and appropriate.
# See the discussion in http://bugs.python.org/issue2578.
if type(first) is type(second):
asserter = self._type_equality_funcs.get(type(first))
if isinstance(asserter, str):
asserter = getattr(self, asserter)
return self._baseAssertEqual
def _baseAssertEqual(self, first, second, msg=None):
"""The default assertEqual implementation, not type specific."""
standardMsg = '%s != %s' % _common_shorten_repr(first, second)
msg = self._formatMessage(msg, standardMsg)
raise self.failureException(msg)
def assertEqual(self, first, second, msg=None):
"""Fail if the two objects are unequal as determined by the '=='
assertion_func = self._getAssertEqualityFunc(first, second)
assertion_func(first, second, msg=msg)
def assertNotEqual(self, first, second, msg=None):
"""Fail if the two objects are equal as determined by the '!='
msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
raise self.failureException(msg)
def assertAlmostEqual(self, first, second, places=None, msg=None,
"""Fail if the two objects are unequal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero, or by comparing that the
difference between the two objects is more than the given
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most significant digit).
If the two objects compare equal then they will automatically
if delta is not None and places is not None:
raise TypeError("specify delta or places not both")
diff = abs(first - second)
standardMsg = '%s != %s within %s delta (%s difference)' % (
if round(diff, places) == 0:
standardMsg = '%s != %s within %r places (%s difference)' % (
msg = self._formatMessage(msg, standardMsg)
raise self.failureException(msg)
def assertNotAlmostEqual(self, first, second, places=None, msg=None,
"""Fail if the two objects are equal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero, or by comparing that the
difference between the two objects is less than the given delta.
Note that decimal places (from zero) are usually not the same
as significant digits (measured from the most significant digit).
Objects that are equal automatically fail.
if delta is not None and places is not None:
raise TypeError("specify delta or places not both")
diff = abs(first - second)
if not (first == second) and diff > delta:
standardMsg = '%s == %s within %s delta (%s difference)' % (
if not (first == second) and round(diff, places) != 0:
standardMsg = '%s == %s within %r places' % (safe_repr(first),
msg = self._formatMessage(msg, standardMsg)