blob: 225a1431ca859366a402df8aa6798a6fe9419c78 [file] [log] [blame]
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001"""Test case implementation"""
2
3import sys
4import functools
5import difflib
Antoine Pitrou0715b9f2013-09-14 19:45:47 +02006import logging
Benjamin Petersonbed7d042009-07-19 21:01:52 +00007import pprint
8import re
9import warnings
Raymond Hettinger6e165b32010-11-27 09:31:37 +000010import collections
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010011import contextlib
Antoine Pitrou96810222014-04-29 01:23:50 +020012import traceback
Benjamin Petersonbed7d042009-07-19 21:01:52 +000013
Benjamin Peterson847a4112010-03-14 15:04:17 +000014from . import result
Florent Xiclunac53ae582011-11-04 08:25:54 +010015from .util import (strclass, safe_repr, _count_diff_all_purpose,
Serhiy Storchaka77622f52013-09-23 23:07:00 +030016 _count_diff_hashable, _common_shorten_repr)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000017
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000018__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000019
Michael Foord9dad32e2010-06-05 13:49:56 +000020
21DIFF_OMITTED = ('\nDiff is %s characters long. '
22 'Set self.maxDiff to None to see it.')
23
Benjamin Petersonbed7d042009-07-19 21:01:52 +000024class SkipTest(Exception):
25 """
26 Raise this exception in a test to skip it.
27
Ezio Melotti265281a2013-03-27 20:11:55 +020028 Usually you can use TestCase.skipTest() or one of the skipping decorators
Benjamin Petersonbed7d042009-07-19 21:01:52 +000029 instead of raising this directly.
30 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000031
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010032class _ShouldStop(Exception):
Benjamin Petersonbed7d042009-07-19 21:01:52 +000033 """
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010034 The test should stop.
Benjamin Petersonbed7d042009-07-19 21:01:52 +000035 """
36
Benjamin Petersonbed7d042009-07-19 21:01:52 +000037class _UnexpectedSuccess(Exception):
38 """
39 The test was supposed to fail, but it didn't!
40 """
Michael Foordb3468f72010-12-19 03:19:47 +000041
42
43class _Outcome(object):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010044 def __init__(self, result=None):
45 self.expecting_failure = False
46 self.result = result
47 self.result_supports_subtests = hasattr(result, "addSubTest")
Michael Foordb3468f72010-12-19 03:19:47 +000048 self.success = True
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010049 self.skipped = []
Michael Foordb3468f72010-12-19 03:19:47 +000050 self.expectedFailure = None
51 self.errors = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010052
53 @contextlib.contextmanager
54 def testPartExecutor(self, test_case, isTest=False):
55 old_success = self.success
56 self.success = True
57 try:
58 yield
59 except KeyboardInterrupt:
60 raise
61 except SkipTest as e:
62 self.success = False
63 self.skipped.append((test_case, str(e)))
64 except _ShouldStop:
65 pass
66 except:
67 exc_info = sys.exc_info()
68 if self.expecting_failure:
69 self.expectedFailure = exc_info
70 else:
71 self.success = False
72 self.errors.append((test_case, exc_info))
Victor Stinner031bd532013-12-09 01:52:50 +010073 # explicitly break a reference cycle:
74 # exc_info -> frame -> exc_info
75 exc_info = None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010076 else:
77 if self.result_supports_subtests and self.success:
78 self.errors.append((test_case, None))
79 finally:
80 self.success = self.success and old_success
Michael Foordb3468f72010-12-19 03:19:47 +000081
Benjamin Petersonbed7d042009-07-19 21:01:52 +000082
83def _id(obj):
84 return obj
85
86def skip(reason):
87 """
88 Unconditionally skip a test.
89 """
90 def decorator(test_item):
Antoine Pitroub05ac862012-04-25 14:56:46 +020091 if not isinstance(test_item, type):
Benjamin Peterson847a4112010-03-14 15:04:17 +000092 @functools.wraps(test_item)
93 def skip_wrapper(*args, **kwargs):
94 raise SkipTest(reason)
95 test_item = skip_wrapper
96
97 test_item.__unittest_skip__ = True
98 test_item.__unittest_skip_why__ = reason
99 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000100 return decorator
101
102def skipIf(condition, reason):
103 """
104 Skip a test if the condition is true.
105 """
106 if condition:
107 return skip(reason)
108 return _id
109
110def skipUnless(condition, reason):
111 """
112 Skip a test unless the condition is true.
113 """
114 if not condition:
115 return skip(reason)
116 return _id
117
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100118def expectedFailure(test_item):
119 test_item.__unittest_expecting_failure__ = True
120 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000121
122
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200123class _BaseTestCaseContext:
124
125 def __init__(self, test_case):
126 self.test_case = test_case
127
128 def _raiseFailure(self, standardMsg):
129 msg = self.test_case._formatMessage(self.msg, standardMsg)
130 raise self.test_case.failureException(msg)
131
Serhiy Storchakae1305032015-05-06 19:13:11 +0300132def _sentinel(*args, **kwargs):
Serhiy Storchaka4b5367c2015-05-06 19:21:00 +0300133 raise AssertionError('Should never be called')
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200134
135class _AssertRaisesBaseContext(_BaseTestCaseContext):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000136
Serhiy Storchakae1305032015-05-06 19:13:11 +0300137 def __init__(self, expected, test_case, callable_obj=_sentinel,
Ezio Melottib4dc2502011-05-06 15:01:41 +0300138 expected_regex=None):
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200139 _BaseTestCaseContext.__init__(self, test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000140 self.expected = expected
Ezio Melottib4dc2502011-05-06 15:01:41 +0300141 self.test_case = test_case
Serhiy Storchakae1305032015-05-06 19:13:11 +0300142 if callable_obj is not _sentinel:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000143 try:
144 self.obj_name = callable_obj.__name__
145 except AttributeError:
146 self.obj_name = str(callable_obj)
147 else:
148 self.obj_name = None
R David Murrayef1c2672014-03-25 15:31:50 -0400149 if expected_regex is not None:
Ezio Melottied3a7d22010-12-01 02:32:32 +0000150 expected_regex = re.compile(expected_regex)
151 self.expected_regex = expected_regex
Ezio Melottib4dc2502011-05-06 15:01:41 +0300152 self.msg = None
153
Ezio Melottib4dc2502011-05-06 15:01:41 +0300154 def handle(self, name, callable_obj, args, kwargs):
155 """
Serhiy Storchakae1305032015-05-06 19:13:11 +0300156 If callable_obj is _sentinel, assertRaises/Warns is being used as a
Ezio Melottib4dc2502011-05-06 15:01:41 +0300157 context manager, so check for a 'msg' kwarg and return self.
Serhiy Storchakae1305032015-05-06 19:13:11 +0300158 If callable_obj is not _sentinel, call it passing args and kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +0300159 """
Serhiy Storchakae1305032015-05-06 19:13:11 +0300160 if callable_obj is _sentinel:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300161 self.msg = kwargs.pop('msg', None)
162 return self
163 with self:
164 callable_obj(*args, **kwargs)
165
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000166
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000167class _AssertRaisesContext(_AssertRaisesBaseContext):
168 """A context manager used to implement TestCase.assertRaises* methods."""
169
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000170 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000171 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000172
173 def __exit__(self, exc_type, exc_value, tb):
174 if exc_type is None:
175 try:
176 exc_name = self.expected.__name__
177 except AttributeError:
178 exc_name = str(self.expected)
179 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300180 self._raiseFailure("{} not raised by {}".format(exc_name,
181 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000182 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300183 self._raiseFailure("{} not raised".format(exc_name))
Antoine Pitrou96810222014-04-29 01:23:50 +0200184 else:
185 traceback.clear_frames(tb)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000186 if not issubclass(exc_type, self.expected):
187 # let unexpected exceptions pass through
188 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000189 # store exception, without traceback, for later retrieval
190 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000191 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000192 return True
193
Ezio Melottied3a7d22010-12-01 02:32:32 +0000194 expected_regex = self.expected_regex
195 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300196 self._raiseFailure('"{}" does not match "{}"'.format(
197 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000198 return True
199
200
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000201class _AssertWarnsContext(_AssertRaisesBaseContext):
202 """A context manager used to implement TestCase.assertWarns* methods."""
203
204 def __enter__(self):
205 # The __warningregistry__'s need to be in a pristine state for tests
206 # to work properly.
207 for v in sys.modules.values():
208 if getattr(v, '__warningregistry__', None):
209 v.__warningregistry__ = {}
210 self.warnings_manager = warnings.catch_warnings(record=True)
211 self.warnings = self.warnings_manager.__enter__()
212 warnings.simplefilter("always", self.expected)
213 return self
214
215 def __exit__(self, exc_type, exc_value, tb):
216 self.warnings_manager.__exit__(exc_type, exc_value, tb)
217 if exc_type is not None:
218 # let unexpected exceptions pass through
219 return
220 try:
221 exc_name = self.expected.__name__
222 except AttributeError:
223 exc_name = str(self.expected)
224 first_matching = None
225 for m in self.warnings:
226 w = m.message
227 if not isinstance(w, self.expected):
228 continue
229 if first_matching is None:
230 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000231 if (self.expected_regex is not None and
232 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000233 continue
234 # store warning for later retrieval
235 self.warning = w
236 self.filename = m.filename
237 self.lineno = m.lineno
238 return
239 # Now we simply try to choose a helpful failure message
240 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300241 self._raiseFailure('"{}" does not match "{}"'.format(
242 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000243 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300244 self._raiseFailure("{} not triggered by {}".format(exc_name,
245 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000246 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300247 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000248
249
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200250
251_LoggingWatcher = collections.namedtuple("_LoggingWatcher",
252 ["records", "output"])
253
254
255class _CapturingHandler(logging.Handler):
256 """
257 A logging handler capturing all (raw and formatted) logging output.
258 """
259
260 def __init__(self):
261 logging.Handler.__init__(self)
262 self.watcher = _LoggingWatcher([], [])
263
264 def flush(self):
265 pass
266
267 def emit(self, record):
268 self.watcher.records.append(record)
269 msg = self.format(record)
270 self.watcher.output.append(msg)
271
272
273
274class _AssertLogsContext(_BaseTestCaseContext):
275 """A context manager used to implement TestCase.assertLogs()."""
276
277 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
278
279 def __init__(self, test_case, logger_name, level):
280 _BaseTestCaseContext.__init__(self, test_case)
281 self.logger_name = logger_name
282 if level:
283 self.level = logging._nameToLevel.get(level, level)
284 else:
285 self.level = logging.INFO
286 self.msg = None
287
288 def __enter__(self):
289 if isinstance(self.logger_name, logging.Logger):
290 logger = self.logger = self.logger_name
291 else:
292 logger = self.logger = logging.getLogger(self.logger_name)
293 formatter = logging.Formatter(self.LOGGING_FORMAT)
294 handler = _CapturingHandler()
295 handler.setFormatter(formatter)
296 self.watcher = handler.watcher
297 self.old_handlers = logger.handlers[:]
298 self.old_level = logger.level
299 self.old_propagate = logger.propagate
300 logger.handlers = [handler]
301 logger.setLevel(self.level)
302 logger.propagate = False
303 return handler.watcher
304
305 def __exit__(self, exc_type, exc_value, tb):
306 self.logger.handlers = self.old_handlers
307 self.logger.propagate = self.old_propagate
308 self.logger.setLevel(self.old_level)
309 if exc_type is not None:
310 # let unexpected exceptions pass through
311 return False
312 if len(self.watcher.records) == 0:
313 self._raiseFailure(
314 "no logs of level {} or higher triggered on {}"
315 .format(logging.getLevelName(self.level), self.logger.name))
316
317
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000318class TestCase(object):
319 """A class whose instances are single test cases.
320
321 By default, the test code itself should be placed in a method named
322 'runTest'.
323
324 If the fixture may be used for many test cases, create as
325 many test methods as are needed. When instantiating such a TestCase
326 subclass, specify in the constructor arguments the name of the test method
327 that the instance is to execute.
328
329 Test authors should subclass TestCase for their own tests. Construction
330 and deconstruction of the test's environment ('fixture') can be
331 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
332
333 If it is necessary to override the __init__ method, the base class
334 __init__ method must always be called. It is important that subclasses
335 should not change the signature of their __init__ method, since instances
336 of the classes are instantiated automatically by parts of the framework
337 in order to be run.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000338
Ezio Melotti31797e52013-03-29 03:42:29 +0200339 When subclassing TestCase, you can set these attributes:
340 * failureException: determines which exception will be raised when
341 the instance's assertion methods fail; test methods raising this
342 exception will be deemed to have 'failed' rather than 'errored'.
343 * longMessage: determines whether long messages (including repr of
344 objects used in assert methods) will be printed on failure in *addition*
345 to any explicit message passed.
346 * maxDiff: sets the maximum length of a diff in failure messages
347 by assert methods using difflib. It is looked up as an instance
348 attribute so can be configured by individual tests if required.
349 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000350
351 failureException = AssertionError
352
Michael Foord5074df62010-12-03 00:53:09 +0000353 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000354
Michael Foord085dfd32010-06-05 12:17:02 +0000355 maxDiff = 80*8
356
Ezio Melottiedd117f2011-04-27 10:20:38 +0300357 # If a string is longer than _diffThreshold, use normal comparison instead
358 # of difflib. See #11763.
359 _diffThreshold = 2**16
360
Benjamin Peterson847a4112010-03-14 15:04:17 +0000361 # Attribute used by TestSuite for classSetUp
362
363 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000364
365 def __init__(self, methodName='runTest'):
366 """Create an instance of the class that will use the named test
367 method when executed. Raises a ValueError if the instance does
368 not have a method with the specified name.
369 """
370 self._testMethodName = methodName
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100371 self._outcome = None
Michael Foord32e1d832011-01-03 17:00:11 +0000372 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000373 try:
374 testMethod = getattr(self, methodName)
375 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000376 if methodName != 'runTest':
377 # we allow instantiation with no explicit method name
378 # but not an *incorrect* or missing method name
379 raise ValueError("no such test method in %s: %s" %
380 (self.__class__, methodName))
381 else:
382 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000383 self._cleanups = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100384 self._subtest = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000385
386 # Map types to custom assertEqual functions that will compare
387 # instances of said type in more detail to generate a more useful
388 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500389 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000390 self.addTypeEqualityFunc(dict, 'assertDictEqual')
391 self.addTypeEqualityFunc(list, 'assertListEqual')
392 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
393 self.addTypeEqualityFunc(set, 'assertSetEqual')
394 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
395 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000396
397 def addTypeEqualityFunc(self, typeobj, function):
398 """Add a type specific assertEqual style function to compare a type.
399
400 This method is for use by TestCase subclasses that need to register
401 their own type equality functions to provide nicer error messages.
402
403 Args:
404 typeobj: The data type to call this function on when both values
405 are of the same type in assertEqual().
406 function: The callable taking two arguments and an optional
407 msg= argument that raises self.failureException with a
408 useful error message when the two arguments are not equal.
409 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000410 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000411
412 def addCleanup(self, function, *args, **kwargs):
413 """Add a function, with arguments, to be called when the test is
414 completed. Functions added are called on a LIFO basis and are
415 called after tearDown on test failure or success.
416
417 Cleanup items are called even if setUp fails (unlike tearDown)."""
418 self._cleanups.append((function, args, kwargs))
419
420 def setUp(self):
421 "Hook method for setting up the test fixture before exercising it."
422 pass
423
424 def tearDown(self):
425 "Hook method for deconstructing the test fixture after testing it."
426 pass
427
Benjamin Peterson847a4112010-03-14 15:04:17 +0000428 @classmethod
429 def setUpClass(cls):
430 "Hook method for setting up class fixture before running tests in the class."
431
432 @classmethod
433 def tearDownClass(cls):
434 "Hook method for deconstructing the class fixture after running all tests in the class."
435
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000436 def countTestCases(self):
437 return 1
438
439 def defaultTestResult(self):
440 return result.TestResult()
441
442 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000443 """Returns a one-line description of the test, or None if no
444 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000445
Michael Foord34c94622010-02-10 15:51:42 +0000446 The default implementation of this method returns the first line of
447 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448 """
Michael Foord34c94622010-02-10 15:51:42 +0000449 doc = self._testMethodDoc
450 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000451
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000452
453 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000454 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000455
456 def __eq__(self, other):
457 if type(self) is not type(other):
458 return NotImplemented
459
460 return self._testMethodName == other._testMethodName
461
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000462 def __hash__(self):
463 return hash((type(self), self._testMethodName))
464
465 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000466 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467
468 def __repr__(self):
469 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000470 (strclass(self.__class__), self._testMethodName)
471
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100472 def _addSkip(self, result, test_case, reason):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000473 addSkip = getattr(result, 'addSkip', None)
474 if addSkip is not None:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100475 addSkip(test_case, reason)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000476 else:
477 warnings.warn("TestResult has no addSkip method, skips not reported",
478 RuntimeWarning, 2)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100479 result.addSuccess(test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000480
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100481 @contextlib.contextmanager
482 def subTest(self, msg=None, **params):
483 """Return a context manager that will return the enclosed block
484 of code in a subtest identified by the optional message and
485 keyword parameters. A failure in the subtest marks the test
486 case as failed but resumes execution at the end of the enclosed
487 block, allowing further test code to be executed.
488 """
489 if not self._outcome.result_supports_subtests:
490 yield
491 return
492 parent = self._subtest
493 if parent is None:
494 params_map = collections.ChainMap(params)
495 else:
496 params_map = parent.params.new_child(params)
497 self._subtest = _SubTest(self, msg, params_map)
Michael Foordb3468f72010-12-19 03:19:47 +0000498 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100499 with self._outcome.testPartExecutor(self._subtest, isTest=True):
500 yield
501 if not self._outcome.success:
502 result = self._outcome.result
503 if result is not None and result.failfast:
504 raise _ShouldStop
505 elif self._outcome.expectedFailure:
506 # If the test is expecting a failure, we really want to
507 # stop now and register the expected failure.
508 raise _ShouldStop
509 finally:
510 self._subtest = parent
511
512 def _feedErrorsToResult(self, result, errors):
513 for test, exc_info in errors:
514 if isinstance(test, _SubTest):
515 result.addSubTest(test.test_case, test, exc_info)
516 elif exc_info is not None:
517 if issubclass(exc_info[0], self.failureException):
518 result.addFailure(test, exc_info)
519 else:
520 result.addError(test, exc_info)
521
522 def _addExpectedFailure(self, result, exc_info):
523 try:
524 addExpectedFailure = result.addExpectedFailure
525 except AttributeError:
526 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
527 RuntimeWarning)
528 result.addSuccess(self)
529 else:
530 addExpectedFailure(self, exc_info)
531
532 def _addUnexpectedSuccess(self, result):
533 try:
534 addUnexpectedSuccess = result.addUnexpectedSuccess
535 except AttributeError:
536 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
537 RuntimeWarning)
538 # We need to pass an actual exception and traceback to addFailure,
539 # otherwise the legacy result can choke.
540 try:
541 raise _UnexpectedSuccess from None
542 except _UnexpectedSuccess:
543 result.addFailure(self, sys.exc_info())
544 else:
545 addUnexpectedSuccess(self)
Michael Foordb3468f72010-12-19 03:19:47 +0000546
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000547 def run(self, result=None):
548 orig_result = result
549 if result is None:
550 result = self.defaultTestResult()
551 startTestRun = getattr(result, 'startTestRun', None)
552 if startTestRun is not None:
553 startTestRun()
554
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000555 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000556
557 testMethod = getattr(self, self._testMethodName)
558 if (getattr(self.__class__, "__unittest_skip__", False) or
559 getattr(testMethod, "__unittest_skip__", False)):
560 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000561 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000562 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
563 or getattr(testMethod, '__unittest_skip_why__', ''))
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100564 self._addSkip(result, self, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000565 finally:
566 result.stopTest(self)
567 return
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100568 expecting_failure = getattr(testMethod,
569 "__unittest_expecting_failure__", False)
Victor Stinner031bd532013-12-09 01:52:50 +0100570 outcome = _Outcome(result)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000571 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100572 self._outcome = outcome
Michael Foordb3468f72010-12-19 03:19:47 +0000573
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100574 with outcome.testPartExecutor(self):
575 self.setUp()
Michael Foordb3468f72010-12-19 03:19:47 +0000576 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100577 outcome.expecting_failure = expecting_failure
578 with outcome.testPartExecutor(self, isTest=True):
579 testMethod()
580 outcome.expecting_failure = False
581 with outcome.testPartExecutor(self):
582 self.tearDown()
Michael Foordb3468f72010-12-19 03:19:47 +0000583
584 self.doCleanups()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100585 for test, reason in outcome.skipped:
586 self._addSkip(result, test, reason)
587 self._feedErrorsToResult(result, outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +0000588 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100589 if expecting_failure:
590 if outcome.expectedFailure:
591 self._addExpectedFailure(result, outcome.expectedFailure)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000592 else:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100593 self._addUnexpectedSuccess(result)
594 else:
595 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400596 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000597 finally:
598 result.stopTest(self)
599 if orig_result is None:
600 stopTestRun = getattr(result, 'stopTestRun', None)
601 if stopTestRun is not None:
602 stopTestRun()
603
Victor Stinner031bd532013-12-09 01:52:50 +0100604 # explicitly break reference cycles:
605 # outcome.errors -> frame -> outcome -> outcome.errors
606 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
607 outcome.errors.clear()
608 outcome.expectedFailure = None
609
610 # clear the outcome, no more needed
611 self._outcome = None
612
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000613 def doCleanups(self):
614 """Execute all cleanup functions. Normally called for you after
615 tearDown."""
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100616 outcome = self._outcome or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000617 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000618 function, args, kwargs = self._cleanups.pop()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100619 with outcome.testPartExecutor(self):
620 function(*args, **kwargs)
Michael Foordb3468f72010-12-19 03:19:47 +0000621
622 # return this for backwards compatibility
623 # even though we no longer us it internally
624 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000625
626 def __call__(self, *args, **kwds):
627 return self.run(*args, **kwds)
628
629 def debug(self):
630 """Run the test without collecting errors in a TestResult"""
631 self.setUp()
632 getattr(self, self._testMethodName)()
633 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000634 while self._cleanups:
635 function, args, kwargs = self._cleanups.pop(-1)
636 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000637
638 def skipTest(self, reason):
639 """Skip this test."""
640 raise SkipTest(reason)
641
642 def fail(self, msg=None):
643 """Fail immediately, with the given message."""
644 raise self.failureException(msg)
645
646 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000647 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000648 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000649 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000650 raise self.failureException(msg)
651
652 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000653 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000654 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000655 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656 raise self.failureException(msg)
657
658 def _formatMessage(self, msg, standardMsg):
659 """Honour the longMessage attribute when generating failure messages.
660 If longMessage is False this means:
661 * Use only an explicit message if it is provided
662 * Otherwise use the standard message for the assert
663
664 If longMessage is True:
665 * Use the standard message
666 * If an explicit message is provided, plus ' : ' and the explicit message
667 """
668 if not self.longMessage:
669 return msg or standardMsg
670 if msg is None:
671 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000672 try:
673 # don't switch to '{}' formatting in Python 2.X
674 # it changes the way unicode input is handled
675 return '%s : %s' % (standardMsg, msg)
676 except UnicodeDecodeError:
677 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000678
Serhiy Storchakae1305032015-05-06 19:13:11 +0300679 def assertRaises(self, excClass, callableObj=_sentinel, *args, **kwargs):
Andrew Svetlov737fb892012-12-18 21:14:22 +0200680 """Fail unless an exception of class excClass is raised
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000681 by callableObj when invoked with arguments args and keyword
682 arguments kwargs. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200683 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000684 deemed to have suffered an error, exactly as for an
685 unexpected exception.
686
Serhiy Storchakae1305032015-05-06 19:13:11 +0300687 If called with callableObj omitted, will return a
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000688 context object used like this::
689
Michael Foord1c42b122010-02-05 22:58:21 +0000690 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000691 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000692
Ezio Melottib4dc2502011-05-06 15:01:41 +0300693 An optional keyword argument 'msg' can be provided when assertRaises
694 is used as a context object.
695
Michael Foord1c42b122010-02-05 22:58:21 +0000696 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000697 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000698 exception after the assertion::
699
700 with self.assertRaises(SomeException) as cm:
701 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000702 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000703 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000704 """
705 context = _AssertRaisesContext(excClass, self, callableObj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300706 return context.handle('assertRaises', callableObj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000707
Serhiy Storchakae1305032015-05-06 19:13:11 +0300708 def assertWarns(self, expected_warning, callable_obj=_sentinel, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000709 """Fail unless a warning of class warnClass is triggered
Ezio Melottib4dc2502011-05-06 15:01:41 +0300710 by callable_obj when invoked with arguments args and keyword
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000711 arguments kwargs. If a different type of warning is
712 triggered, it will not be handled: depending on the other
713 warning filtering rules in effect, it might be silenced, printed
714 out, or raised as an exception.
715
Serhiy Storchakae1305032015-05-06 19:13:11 +0300716 If called with callable_obj omitted, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000717 context object used like this::
718
719 with self.assertWarns(SomeWarning):
720 do_something()
721
Ezio Melottib4dc2502011-05-06 15:01:41 +0300722 An optional keyword argument 'msg' can be provided when assertWarns
723 is used as a context object.
724
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000725 The context manager keeps a reference to the first matching
726 warning as the 'warning' attribute; similarly, the 'filename'
727 and 'lineno' attributes give you information about the line
728 of Python code from which the warning was triggered.
729 This allows you to inspect the warning after the assertion::
730
731 with self.assertWarns(SomeWarning) as cm:
732 do_something()
733 the_warning = cm.warning
734 self.assertEqual(the_warning.some_attribute, 147)
735 """
736 context = _AssertWarnsContext(expected_warning, self, callable_obj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300737 return context.handle('assertWarns', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000738
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200739 def assertLogs(self, logger=None, level=None):
740 """Fail unless a log message of level *level* or higher is emitted
741 on *logger_name* or its children. If omitted, *level* defaults to
742 INFO and *logger* defaults to the root logger.
743
744 This method must be used as a context manager, and will yield
745 a recording object with two attributes: `output` and `records`.
746 At the end of the context manager, the `output` attribute will
747 be a list of the matching formatted log messages and the
748 `records` attribute will be a list of the corresponding LogRecord
749 objects.
750
751 Example::
752
753 with self.assertLogs('foo', level='INFO') as cm:
754 logging.getLogger('foo').info('first message')
755 logging.getLogger('foo.bar').error('second message')
756 self.assertEqual(cm.output, ['INFO:foo:first message',
757 'ERROR:foo.bar:second message'])
758 """
759 return _AssertLogsContext(self, logger, level)
760
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000761 def _getAssertEqualityFunc(self, first, second):
762 """Get a detailed comparison function for the types of the two args.
763
764 Returns: A callable accepting (first, second, msg=None) that will
765 raise a failure exception if first != second with a useful human
766 readable error message for those types.
767 """
768 #
769 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
770 # and vice versa. I opted for the conservative approach in case
771 # subclasses are not intended to be compared in detail to their super
772 # class instances using a type equality func. This means testing
773 # subtypes won't automagically use the detailed comparison. Callers
774 # should use their type specific assertSpamEqual method to compare
775 # subclasses if the detailed comparison is desired and appropriate.
776 # See the discussion in http://bugs.python.org/issue2578.
777 #
778 if type(first) is type(second):
779 asserter = self._type_equality_funcs.get(type(first))
780 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500781 if isinstance(asserter, str):
782 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000783 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000784
785 return self._baseAssertEqual
786
787 def _baseAssertEqual(self, first, second, msg=None):
788 """The default assertEqual implementation, not type specific."""
789 if not first == second:
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300790 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000791 msg = self._formatMessage(msg, standardMsg)
792 raise self.failureException(msg)
793
794 def assertEqual(self, first, second, msg=None):
795 """Fail if the two objects are unequal as determined by the '=='
796 operator.
797 """
798 assertion_func = self._getAssertEqualityFunc(first, second)
799 assertion_func(first, second, msg=msg)
800
801 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200802 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000803 operator.
804 """
805 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000806 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
807 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000808 raise self.failureException(msg)
809
Michael Foord321d0592010-11-02 13:44:51 +0000810 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000811 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000812 """Fail if the two objects are unequal as determined by their
813 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000814 (default 7) and comparing to zero, or by comparing that the
815 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000816
817 Note that decimal places (from zero) are usually not the same
818 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000819
820 If the two objects compare equal then they will automatically
821 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000822 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000823 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000824 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000825 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000826 if delta is not None and places is not None:
827 raise TypeError("specify delta or places not both")
828
829 if delta is not None:
830 if abs(first - second) <= delta:
831 return
832
833 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
834 safe_repr(second),
835 safe_repr(delta))
836 else:
837 if places is None:
838 places = 7
839
840 if round(abs(second-first), places) == 0:
841 return
842
Benjamin Peterson847a4112010-03-14 15:04:17 +0000843 standardMsg = '%s != %s within %r places' % (safe_repr(first),
844 safe_repr(second),
845 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000846 msg = self._formatMessage(msg, standardMsg)
847 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000848
Michael Foord321d0592010-11-02 13:44:51 +0000849 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000850 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000851 """Fail if the two objects are equal as determined by their
852 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000853 (default 7) and comparing to zero, or by comparing that the
854 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000855
856 Note that decimal places (from zero) are usually not the same
857 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000858
859 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000860 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000861 if delta is not None and places is not None:
862 raise TypeError("specify delta or places not both")
863 if delta is not None:
864 if not (first == second) and abs(first - second) > delta:
865 return
866 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
867 safe_repr(second),
868 safe_repr(delta))
869 else:
870 if places is None:
871 places = 7
872 if not (first == second) and round(abs(second-first), places) != 0:
873 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000874 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000875 safe_repr(second),
876 places)
877
878 msg = self._formatMessage(msg, standardMsg)
879 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000880
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000881
Michael Foord085dfd32010-06-05 12:17:02 +0000882 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000883 """An equality assertion for ordered sequences (like lists and tuples).
884
R. David Murrayad13f222010-01-29 22:17:58 +0000885 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000886 which can be indexed, has a length, and has an equality operator.
887
888 Args:
889 seq1: The first sequence to compare.
890 seq2: The second sequence to compare.
891 seq_type: The expected datatype of the sequences, or None if no
892 datatype should be enforced.
893 msg: Optional message to use on failure instead of a list of
894 differences.
895 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400896 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000897 seq_type_name = seq_type.__name__
898 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000899 raise self.failureException('First sequence is not a %s: %s'
900 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000901 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000902 raise self.failureException('Second sequence is not a %s: %s'
903 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000904 else:
905 seq_type_name = "sequence"
906
907 differing = None
908 try:
909 len1 = len(seq1)
910 except (TypeError, NotImplementedError):
911 differing = 'First %s has no length. Non-sequence?' % (
912 seq_type_name)
913
914 if differing is None:
915 try:
916 len2 = len(seq2)
917 except (TypeError, NotImplementedError):
918 differing = 'Second %s has no length. Non-sequence?' % (
919 seq_type_name)
920
921 if differing is None:
922 if seq1 == seq2:
923 return
924
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300925 differing = '%ss differ: %s != %s\n' % (
926 (seq_type_name.capitalize(),) +
927 _common_shorten_repr(seq1, seq2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000928
929 for i in range(min(len1, len2)):
930 try:
931 item1 = seq1[i]
932 except (TypeError, IndexError, NotImplementedError):
933 differing += ('\nUnable to index element %d of first %s\n' %
934 (i, seq_type_name))
935 break
936
937 try:
938 item2 = seq2[i]
939 except (TypeError, IndexError, NotImplementedError):
940 differing += ('\nUnable to index element %d of second %s\n' %
941 (i, seq_type_name))
942 break
943
944 if item1 != item2:
945 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
946 (i, item1, item2))
947 break
948 else:
949 if (len1 == len2 and seq_type is None and
950 type(seq1) != type(seq2)):
951 # The sequences are the same, but have differing types.
952 return
953
954 if len1 > len2:
955 differing += ('\nFirst %s contains %d additional '
956 'elements.\n' % (seq_type_name, len1 - len2))
957 try:
958 differing += ('First extra element %d:\n%s\n' %
959 (len2, seq1[len2]))
960 except (TypeError, IndexError, NotImplementedError):
961 differing += ('Unable to index element %d '
962 'of first %s\n' % (len2, seq_type_name))
963 elif len1 < len2:
964 differing += ('\nSecond %s contains %d additional '
965 'elements.\n' % (seq_type_name, len2 - len1))
966 try:
967 differing += ('First extra element %d:\n%s\n' %
968 (len1, seq2[len1]))
969 except (TypeError, IndexError, NotImplementedError):
970 differing += ('Unable to index element %d '
971 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000972 standardMsg = differing
973 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000974 difflib.ndiff(pprint.pformat(seq1).splitlines(),
975 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000976
977 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000978 msg = self._formatMessage(msg, standardMsg)
979 self.fail(msg)
980
Michael Foord085dfd32010-06-05 12:17:02 +0000981 def _truncateMessage(self, message, diff):
982 max_diff = self.maxDiff
983 if max_diff is None or len(diff) <= max_diff:
984 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000985 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000986
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000987 def assertListEqual(self, list1, list2, msg=None):
988 """A list-specific equality assertion.
989
990 Args:
991 list1: The first list to compare.
992 list2: The second list to compare.
993 msg: Optional message to use on failure instead of a list of
994 differences.
995
996 """
997 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
998
999 def assertTupleEqual(self, tuple1, tuple2, msg=None):
1000 """A tuple-specific equality assertion.
1001
1002 Args:
1003 tuple1: The first tuple to compare.
1004 tuple2: The second tuple to compare.
1005 msg: Optional message to use on failure instead of a list of
1006 differences.
1007 """
1008 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1009
1010 def assertSetEqual(self, set1, set2, msg=None):
1011 """A set-specific equality assertion.
1012
1013 Args:
1014 set1: The first set to compare.
1015 set2: The second set to compare.
1016 msg: Optional message to use on failure instead of a list of
1017 differences.
1018
Michael Foord91c9da32010-03-20 17:21:27 +00001019 assertSetEqual uses ducktyping to support different types of sets, and
1020 is optimized for sets specifically (parameters must support a
1021 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001022 """
1023 try:
1024 difference1 = set1.difference(set2)
1025 except TypeError as e:
1026 self.fail('invalid type when attempting set difference: %s' % e)
1027 except AttributeError as e:
1028 self.fail('first argument does not support set difference: %s' % e)
1029
1030 try:
1031 difference2 = set2.difference(set1)
1032 except TypeError as e:
1033 self.fail('invalid type when attempting set difference: %s' % e)
1034 except AttributeError as e:
1035 self.fail('second argument does not support set difference: %s' % e)
1036
1037 if not (difference1 or difference2):
1038 return
1039
1040 lines = []
1041 if difference1:
1042 lines.append('Items in the first set but not the second:')
1043 for item in difference1:
1044 lines.append(repr(item))
1045 if difference2:
1046 lines.append('Items in the second set but not the first:')
1047 for item in difference2:
1048 lines.append(repr(item))
1049
1050 standardMsg = '\n'.join(lines)
1051 self.fail(self._formatMessage(msg, standardMsg))
1052
1053 def assertIn(self, member, container, msg=None):
1054 """Just like self.assertTrue(a in b), but with a nicer default message."""
1055 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001056 standardMsg = '%s not found in %s' % (safe_repr(member),
1057 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001058 self.fail(self._formatMessage(msg, standardMsg))
1059
1060 def assertNotIn(self, member, container, msg=None):
1061 """Just like self.assertTrue(a not in b), but with a nicer default message."""
1062 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001063 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1064 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001065 self.fail(self._formatMessage(msg, standardMsg))
1066
1067 def assertIs(self, expr1, expr2, msg=None):
1068 """Just like self.assertTrue(a is b), but with a nicer default message."""
1069 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001070 standardMsg = '%s is not %s' % (safe_repr(expr1),
1071 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001072 self.fail(self._formatMessage(msg, standardMsg))
1073
1074 def assertIsNot(self, expr1, expr2, msg=None):
1075 """Just like self.assertTrue(a is not b), but with a nicer default message."""
1076 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001077 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001078 self.fail(self._formatMessage(msg, standardMsg))
1079
1080 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001081 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1082 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001083
1084 if d1 != d2:
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001085 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
Michael Foord085dfd32010-06-05 12:17:02 +00001086 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001087 pprint.pformat(d1).splitlines(),
1088 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +00001089 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001090 self.fail(self._formatMessage(msg, standardMsg))
1091
Ezio Melotti0f535012011-04-03 18:02:13 +03001092 def assertDictContainsSubset(self, subset, dictionary, msg=None):
1093 """Checks whether dictionary is a superset of subset."""
1094 warnings.warn('assertDictContainsSubset is deprecated',
1095 DeprecationWarning)
1096 missing = []
1097 mismatched = []
1098 for key, value in subset.items():
1099 if key not in dictionary:
1100 missing.append(key)
1101 elif value != dictionary[key]:
1102 mismatched.append('%s, expected: %s, actual: %s' %
1103 (safe_repr(key), safe_repr(value),
1104 safe_repr(dictionary[key])))
1105
1106 if not (missing or mismatched):
1107 return
1108
1109 standardMsg = ''
1110 if missing:
1111 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1112 missing)
1113 if mismatched:
1114 if standardMsg:
1115 standardMsg += '; '
1116 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1117
1118 self.fail(self._formatMessage(msg, standardMsg))
1119
1120
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001121 def assertCountEqual(self, first, second, msg=None):
1122 """An unordered sequence comparison asserting that the same elements,
1123 regardless of order. If the same element occurs more than once,
1124 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001125
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001126 self.assertEqual(Counter(list(first)),
1127 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001128
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001129 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001130 - [0, 1, 1] and [1, 0, 1] compare equal.
1131 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001132
Michael Foord8442a602010-03-20 16:58:04 +00001133 """
Michael Foorde180d392011-01-28 19:51:48 +00001134 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001135 try:
Michael Foorde180d392011-01-28 19:51:48 +00001136 first = collections.Counter(first_seq)
1137 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001138 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001139 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001140 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001141 else:
Michael Foorde180d392011-01-28 19:51:48 +00001142 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001143 return
Michael Foorde180d392011-01-28 19:51:48 +00001144 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001145
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001146 if differences:
1147 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001148 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001149 diffMsg = '\n'.join(lines)
1150 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1151 msg = self._formatMessage(msg, standardMsg)
1152 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001153
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001154 def assertMultiLineEqual(self, first, second, msg=None):
1155 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001156 self.assertIsInstance(first, str, 'First argument is not a string')
1157 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001158
1159 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001160 # don't use difflib if the strings are too long
1161 if (len(first) > self._diffThreshold or
1162 len(second) > self._diffThreshold):
1163 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001164 firstlines = first.splitlines(keepends=True)
1165 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001166 if len(firstlines) == 1 and first.strip('\r\n') == first:
1167 firstlines = [first + '\n']
1168 secondlines = [second + '\n']
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001169 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Michael Foordc653ce32010-07-10 13:52:22 +00001170 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001171 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001172 self.fail(self._formatMessage(msg, standardMsg))
1173
1174 def assertLess(self, a, b, msg=None):
1175 """Just like self.assertTrue(a < b), but with a nicer default message."""
1176 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001177 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001178 self.fail(self._formatMessage(msg, standardMsg))
1179
1180 def assertLessEqual(self, a, b, msg=None):
1181 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1182 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001183 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001184 self.fail(self._formatMessage(msg, standardMsg))
1185
1186 def assertGreater(self, a, b, msg=None):
1187 """Just like self.assertTrue(a > b), but with a nicer default message."""
1188 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001189 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001190 self.fail(self._formatMessage(msg, standardMsg))
1191
1192 def assertGreaterEqual(self, a, b, msg=None):
1193 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1194 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001195 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001196 self.fail(self._formatMessage(msg, standardMsg))
1197
1198 def assertIsNone(self, obj, msg=None):
1199 """Same as self.assertTrue(obj is None), with a nicer default message."""
1200 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001201 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001202 self.fail(self._formatMessage(msg, standardMsg))
1203
1204 def assertIsNotNone(self, obj, msg=None):
1205 """Included for symmetry with assertIsNone."""
1206 if obj is None:
1207 standardMsg = 'unexpectedly None'
1208 self.fail(self._formatMessage(msg, standardMsg))
1209
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001210 def assertIsInstance(self, obj, cls, msg=None):
1211 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1212 default message."""
1213 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001214 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001215 self.fail(self._formatMessage(msg, standardMsg))
1216
1217 def assertNotIsInstance(self, obj, cls, msg=None):
1218 """Included for symmetry with assertIsInstance."""
1219 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001220 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001221 self.fail(self._formatMessage(msg, standardMsg))
1222
Ezio Melottied3a7d22010-12-01 02:32:32 +00001223 def assertRaisesRegex(self, expected_exception, expected_regex,
Serhiy Storchakae1305032015-05-06 19:13:11 +03001224 callable_obj=_sentinel, *args, **kwargs):
Ezio Melottied3a7d22010-12-01 02:32:32 +00001225 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001226
1227 Args:
1228 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001229 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001230 to be found in error message.
1231 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001232 msg: Optional message used in case of failure. Can only be used
1233 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001234 args: Extra args.
1235 kwargs: Extra kwargs.
1236 """
1237 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001238 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001239
1240 return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001241
Ezio Melottied3a7d22010-12-01 02:32:32 +00001242 def assertWarnsRegex(self, expected_warning, expected_regex,
Serhiy Storchakae1305032015-05-06 19:13:11 +03001243 callable_obj=_sentinel, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001244 """Asserts that the message in a triggered warning matches a regexp.
1245 Basic functioning is similar to assertWarns() with the addition
1246 that only warnings whose messages also match the regular expression
1247 are considered successful matches.
1248
1249 Args:
1250 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001251 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001252 to be found in error message.
1253 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001254 msg: Optional message used in case of failure. Can only be used
1255 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001256 args: Extra args.
1257 kwargs: Extra kwargs.
1258 """
1259 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001260 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001261 return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001262
Ezio Melottied3a7d22010-12-01 02:32:32 +00001263 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001264 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001265 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001266 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001267 expected_regex = re.compile(expected_regex)
1268 if not expected_regex.search(text):
1269 msg = msg or "Regex didn't match"
1270 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001271 raise self.failureException(msg)
1272
Ezio Melotti8f776302010-12-10 02:32:05 +00001273 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001274 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001275 if isinstance(unexpected_regex, (str, bytes)):
1276 unexpected_regex = re.compile(unexpected_regex)
1277 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001278 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001279 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001280 msg = '%s: %r matches %r in %r' % (msg,
1281 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001282 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001283 text)
1284 raise self.failureException(msg)
1285
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001286
Ezio Melottied3a7d22010-12-01 02:32:32 +00001287 def _deprecate(original_func):
1288 def deprecated_func(*args, **kwargs):
1289 warnings.warn(
1290 'Please use {0} instead.'.format(original_func.__name__),
1291 DeprecationWarning, 2)
1292 return original_func(*args, **kwargs)
1293 return deprecated_func
1294
Ezio Melotti361467e2011-04-03 17:37:58 +03001295 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001296 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1297 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1298 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1299 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1300 failUnless = assert_ = _deprecate(assertTrue)
1301 failUnlessRaises = _deprecate(assertRaises)
1302 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001303 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1304 assertRegexpMatches = _deprecate(assertRegex)
1305
1306
1307
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001308class FunctionTestCase(TestCase):
1309 """A test case that wraps a test function.
1310
1311 This is useful for slipping pre-existing test functions into the
1312 unittest framework. Optionally, set-up and tidy-up functions can be
1313 supplied. As with TestCase, the tidy-up ('tearDown') function will
1314 always be called if the set-up ('setUp') function ran successfully.
1315 """
1316
1317 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1318 super(FunctionTestCase, self).__init__()
1319 self._setUpFunc = setUp
1320 self._tearDownFunc = tearDown
1321 self._testFunc = testFunc
1322 self._description = description
1323
1324 def setUp(self):
1325 if self._setUpFunc is not None:
1326 self._setUpFunc()
1327
1328 def tearDown(self):
1329 if self._tearDownFunc is not None:
1330 self._tearDownFunc()
1331
1332 def runTest(self):
1333 self._testFunc()
1334
1335 def id(self):
1336 return self._testFunc.__name__
1337
1338 def __eq__(self, other):
1339 if not isinstance(other, self.__class__):
1340 return NotImplemented
1341
1342 return self._setUpFunc == other._setUpFunc and \
1343 self._tearDownFunc == other._tearDownFunc and \
1344 self._testFunc == other._testFunc and \
1345 self._description == other._description
1346
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001347 def __hash__(self):
1348 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1349 self._testFunc, self._description))
1350
1351 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001352 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001353 self._testFunc.__name__)
1354
1355 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001356 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001357 self._testFunc)
1358
1359 def shortDescription(self):
1360 if self._description is not None:
1361 return self._description
1362 doc = self._testFunc.__doc__
1363 return doc and doc.split("\n")[0].strip() or None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001364
1365
1366class _SubTest(TestCase):
1367
1368 def __init__(self, test_case, message, params):
1369 super().__init__()
1370 self._message = message
1371 self.test_case = test_case
1372 self.params = params
1373 self.failureException = test_case.failureException
1374
1375 def runTest(self):
1376 raise NotImplementedError("subtests cannot be run directly")
1377
1378 def _subDescription(self):
1379 parts = []
1380 if self._message:
1381 parts.append("[{}]".format(self._message))
1382 if self.params:
1383 params_desc = ', '.join(
1384 "{}={!r}".format(k, v)
1385 for (k, v) in sorted(self.params.items()))
1386 parts.append("({})".format(params_desc))
1387 return " ".join(parts) or '(<subtest>)'
1388
1389 def id(self):
1390 return "{} {}".format(self.test_case.id(), self._subDescription())
1391
1392 def shortDescription(self):
1393 """Returns a one-line description of the subtest, or None if no
1394 description has been provided.
1395 """
1396 return self.test_case.shortDescription()
1397
1398 def __str__(self):
1399 return "{} {}".format(self.test_case, self._subDescription())