blob: 1faa6b641f2d75502f220ecfdf7a9bc361c255b1 [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
Berker Peksag16ea19f2016-09-21 19:34:15 +030020_subtest_msg_sentinel = object()
Michael Foord9dad32e2010-06-05 13:49:56 +000021
22DIFF_OMITTED = ('\nDiff is %s characters long. '
23 'Set self.maxDiff to None to see it.')
24
Benjamin Petersonbed7d042009-07-19 21:01:52 +000025class SkipTest(Exception):
26 """
27 Raise this exception in a test to skip it.
28
Ezio Melotti265281a2013-03-27 20:11:55 +020029 Usually you can use TestCase.skipTest() or one of the skipping decorators
Benjamin Petersonbed7d042009-07-19 21:01:52 +000030 instead of raising this directly.
31 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000032
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010033class _ShouldStop(Exception):
Benjamin Petersonbed7d042009-07-19 21:01:52 +000034 """
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010035 The test should stop.
Benjamin Petersonbed7d042009-07-19 21:01:52 +000036 """
37
Benjamin Petersonbed7d042009-07-19 21:01:52 +000038class _UnexpectedSuccess(Exception):
39 """
40 The test was supposed to fail, but it didn't!
41 """
Michael Foordb3468f72010-12-19 03:19:47 +000042
43
44class _Outcome(object):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010045 def __init__(self, result=None):
46 self.expecting_failure = False
47 self.result = result
48 self.result_supports_subtests = hasattr(result, "addSubTest")
Michael Foordb3468f72010-12-19 03:19:47 +000049 self.success = True
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010050 self.skipped = []
Michael Foordb3468f72010-12-19 03:19:47 +000051 self.expectedFailure = None
52 self.errors = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010053
54 @contextlib.contextmanager
55 def testPartExecutor(self, test_case, isTest=False):
56 old_success = self.success
57 self.success = True
58 try:
59 yield
60 except KeyboardInterrupt:
61 raise
62 except SkipTest as e:
63 self.success = False
64 self.skipped.append((test_case, str(e)))
65 except _ShouldStop:
66 pass
67 except:
68 exc_info = sys.exc_info()
69 if self.expecting_failure:
70 self.expectedFailure = exc_info
71 else:
72 self.success = False
73 self.errors.append((test_case, exc_info))
Victor Stinner031bd532013-12-09 01:52:50 +010074 # explicitly break a reference cycle:
75 # exc_info -> frame -> exc_info
76 exc_info = None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010077 else:
78 if self.result_supports_subtests and self.success:
79 self.errors.append((test_case, None))
80 finally:
81 self.success = self.success and old_success
Michael Foordb3468f72010-12-19 03:19:47 +000082
Benjamin Petersonbed7d042009-07-19 21:01:52 +000083
84def _id(obj):
85 return obj
86
87def skip(reason):
88 """
89 Unconditionally skip a test.
90 """
91 def decorator(test_item):
Antoine Pitroub05ac862012-04-25 14:56:46 +020092 if not isinstance(test_item, type):
Benjamin Peterson847a4112010-03-14 15:04:17 +000093 @functools.wraps(test_item)
94 def skip_wrapper(*args, **kwargs):
95 raise SkipTest(reason)
96 test_item = skip_wrapper
97
98 test_item.__unittest_skip__ = True
99 test_item.__unittest_skip_why__ = reason
100 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000101 return decorator
102
103def skipIf(condition, reason):
104 """
105 Skip a test if the condition is true.
106 """
107 if condition:
108 return skip(reason)
109 return _id
110
111def skipUnless(condition, reason):
112 """
113 Skip a test unless the condition is true.
114 """
115 if not condition:
116 return skip(reason)
117 return _id
118
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100119def expectedFailure(test_item):
120 test_item.__unittest_expecting_failure__ = True
121 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000122
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300123def _is_subtype(expected, basetype):
124 if isinstance(expected, tuple):
125 return all(_is_subtype(e, basetype) for e in expected)
126 return isinstance(expected, type) and issubclass(expected, basetype)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000127
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200128class _BaseTestCaseContext:
129
130 def __init__(self, test_case):
131 self.test_case = test_case
132
133 def _raiseFailure(self, standardMsg):
134 msg = self.test_case._formatMessage(self.msg, standardMsg)
135 raise self.test_case.failureException(msg)
136
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200137class _AssertRaisesBaseContext(_BaseTestCaseContext):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300139 def __init__(self, expected, test_case, expected_regex=None):
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200140 _BaseTestCaseContext.__init__(self, test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000141 self.expected = expected
Ezio Melottib4dc2502011-05-06 15:01:41 +0300142 self.test_case = test_case
R David Murrayef1c2672014-03-25 15:31:50 -0400143 if expected_regex is not None:
Ezio Melottied3a7d22010-12-01 02:32:32 +0000144 expected_regex = re.compile(expected_regex)
145 self.expected_regex = expected_regex
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300146 self.obj_name = None
Ezio Melottib4dc2502011-05-06 15:01:41 +0300147 self.msg = None
148
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300149 def handle(self, name, args, kwargs):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300150 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300151 If args is empty, assertRaises/Warns is being used as a
Ezio Melottib4dc2502011-05-06 15:01:41 +0300152 context manager, so check for a 'msg' kwarg and return self.
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300153 If args is not empty, call a callable passing positional and keyword
154 arguments.
Ezio Melottib4dc2502011-05-06 15:01:41 +0300155 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300156 try:
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200157 if not _is_subtype(self.expected, self._base_type):
158 raise TypeError('%s() arg 1 must be %s' %
159 (name, self._base_type_str))
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200160 if not args:
161 self.msg = kwargs.pop('msg', None)
162 if kwargs:
Serhiy Storchaka77d57812018-08-19 10:00:11 +0300163 raise TypeError('%r is an invalid keyword argument for '
164 'this function' % (next(iter(kwargs)),))
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200165 return self
166
167 callable_obj, *args = args
168 try:
169 self.obj_name = callable_obj.__name__
170 except AttributeError:
171 self.obj_name = str(callable_obj)
172 with self:
173 callable_obj(*args, **kwargs)
174 finally:
175 # bpo-23890: manually break a reference cycle
176 self = None
Ezio Melottib4dc2502011-05-06 15:01:41 +0300177
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000178
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000179class _AssertRaisesContext(_AssertRaisesBaseContext):
180 """A context manager used to implement TestCase.assertRaises* methods."""
181
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300182 _base_type = BaseException
183 _base_type_str = 'an exception type or tuple of exception types'
184
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000185 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000186 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000187
188 def __exit__(self, exc_type, exc_value, tb):
189 if exc_type is None:
190 try:
191 exc_name = self.expected.__name__
192 except AttributeError:
193 exc_name = str(self.expected)
194 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300195 self._raiseFailure("{} not raised by {}".format(exc_name,
196 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000197 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300198 self._raiseFailure("{} not raised".format(exc_name))
Antoine Pitrou96810222014-04-29 01:23:50 +0200199 else:
200 traceback.clear_frames(tb)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000201 if not issubclass(exc_type, self.expected):
202 # let unexpected exceptions pass through
203 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000204 # store exception, without traceback, for later retrieval
205 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000206 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000207 return True
208
Ezio Melottied3a7d22010-12-01 02:32:32 +0000209 expected_regex = self.expected_regex
210 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300211 self._raiseFailure('"{}" does not match "{}"'.format(
212 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000213 return True
214
215
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000216class _AssertWarnsContext(_AssertRaisesBaseContext):
217 """A context manager used to implement TestCase.assertWarns* methods."""
218
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300219 _base_type = Warning
220 _base_type_str = 'a warning type or tuple of warning types'
221
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000222 def __enter__(self):
223 # The __warningregistry__'s need to be in a pristine state for tests
224 # to work properly.
225 for v in sys.modules.values():
226 if getattr(v, '__warningregistry__', None):
227 v.__warningregistry__ = {}
228 self.warnings_manager = warnings.catch_warnings(record=True)
229 self.warnings = self.warnings_manager.__enter__()
230 warnings.simplefilter("always", self.expected)
231 return self
232
233 def __exit__(self, exc_type, exc_value, tb):
234 self.warnings_manager.__exit__(exc_type, exc_value, tb)
235 if exc_type is not None:
236 # let unexpected exceptions pass through
237 return
238 try:
239 exc_name = self.expected.__name__
240 except AttributeError:
241 exc_name = str(self.expected)
242 first_matching = None
243 for m in self.warnings:
244 w = m.message
245 if not isinstance(w, self.expected):
246 continue
247 if first_matching is None:
248 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000249 if (self.expected_regex is not None and
250 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000251 continue
252 # store warning for later retrieval
253 self.warning = w
254 self.filename = m.filename
255 self.lineno = m.lineno
256 return
257 # Now we simply try to choose a helpful failure message
258 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300259 self._raiseFailure('"{}" does not match "{}"'.format(
260 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000261 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300262 self._raiseFailure("{} not triggered by {}".format(exc_name,
263 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000264 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300265 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000266
267
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200268
269_LoggingWatcher = collections.namedtuple("_LoggingWatcher",
270 ["records", "output"])
271
272
273class _CapturingHandler(logging.Handler):
274 """
275 A logging handler capturing all (raw and formatted) logging output.
276 """
277
278 def __init__(self):
279 logging.Handler.__init__(self)
280 self.watcher = _LoggingWatcher([], [])
281
282 def flush(self):
283 pass
284
285 def emit(self, record):
286 self.watcher.records.append(record)
287 msg = self.format(record)
288 self.watcher.output.append(msg)
289
290
291
292class _AssertLogsContext(_BaseTestCaseContext):
293 """A context manager used to implement TestCase.assertLogs()."""
294
295 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
296
297 def __init__(self, test_case, logger_name, level):
298 _BaseTestCaseContext.__init__(self, test_case)
299 self.logger_name = logger_name
300 if level:
301 self.level = logging._nameToLevel.get(level, level)
302 else:
303 self.level = logging.INFO
304 self.msg = None
305
306 def __enter__(self):
307 if isinstance(self.logger_name, logging.Logger):
308 logger = self.logger = self.logger_name
309 else:
310 logger = self.logger = logging.getLogger(self.logger_name)
311 formatter = logging.Formatter(self.LOGGING_FORMAT)
312 handler = _CapturingHandler()
313 handler.setFormatter(formatter)
314 self.watcher = handler.watcher
315 self.old_handlers = logger.handlers[:]
316 self.old_level = logger.level
317 self.old_propagate = logger.propagate
318 logger.handlers = [handler]
319 logger.setLevel(self.level)
320 logger.propagate = False
321 return handler.watcher
322
323 def __exit__(self, exc_type, exc_value, tb):
324 self.logger.handlers = self.old_handlers
325 self.logger.propagate = self.old_propagate
326 self.logger.setLevel(self.old_level)
327 if exc_type is not None:
328 # let unexpected exceptions pass through
329 return False
330 if len(self.watcher.records) == 0:
331 self._raiseFailure(
332 "no logs of level {} or higher triggered on {}"
333 .format(logging.getLevelName(self.level), self.logger.name))
334
335
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300336class _OrderedChainMap(collections.ChainMap):
337 def __iter__(self):
338 seen = set()
339 for mapping in self.maps:
340 for k in mapping:
341 if k not in seen:
342 seen.add(k)
343 yield k
344
345
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000346class TestCase(object):
347 """A class whose instances are single test cases.
348
349 By default, the test code itself should be placed in a method named
350 'runTest'.
351
352 If the fixture may be used for many test cases, create as
353 many test methods as are needed. When instantiating such a TestCase
354 subclass, specify in the constructor arguments the name of the test method
355 that the instance is to execute.
356
357 Test authors should subclass TestCase for their own tests. Construction
358 and deconstruction of the test's environment ('fixture') can be
359 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
360
361 If it is necessary to override the __init__ method, the base class
362 __init__ method must always be called. It is important that subclasses
363 should not change the signature of their __init__ method, since instances
364 of the classes are instantiated automatically by parts of the framework
365 in order to be run.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000366
Ezio Melotti31797e52013-03-29 03:42:29 +0200367 When subclassing TestCase, you can set these attributes:
368 * failureException: determines which exception will be raised when
369 the instance's assertion methods fail; test methods raising this
370 exception will be deemed to have 'failed' rather than 'errored'.
371 * longMessage: determines whether long messages (including repr of
372 objects used in assert methods) will be printed on failure in *addition*
373 to any explicit message passed.
374 * maxDiff: sets the maximum length of a diff in failure messages
375 by assert methods using difflib. It is looked up as an instance
376 attribute so can be configured by individual tests if required.
377 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000378
379 failureException = AssertionError
380
Michael Foord5074df62010-12-03 00:53:09 +0000381 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000382
Michael Foord085dfd32010-06-05 12:17:02 +0000383 maxDiff = 80*8
384
Ezio Melottiedd117f2011-04-27 10:20:38 +0300385 # If a string is longer than _diffThreshold, use normal comparison instead
386 # of difflib. See #11763.
387 _diffThreshold = 2**16
388
Benjamin Peterson847a4112010-03-14 15:04:17 +0000389 # Attribute used by TestSuite for classSetUp
390
391 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000392
393 def __init__(self, methodName='runTest'):
394 """Create an instance of the class that will use the named test
395 method when executed. Raises a ValueError if the instance does
396 not have a method with the specified name.
397 """
398 self._testMethodName = methodName
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100399 self._outcome = None
Michael Foord32e1d832011-01-03 17:00:11 +0000400 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000401 try:
402 testMethod = getattr(self, methodName)
403 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000404 if methodName != 'runTest':
405 # we allow instantiation with no explicit method name
406 # but not an *incorrect* or missing method name
407 raise ValueError("no such test method in %s: %s" %
408 (self.__class__, methodName))
409 else:
410 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000411 self._cleanups = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100412 self._subtest = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000413
414 # Map types to custom assertEqual functions that will compare
415 # instances of said type in more detail to generate a more useful
416 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500417 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000418 self.addTypeEqualityFunc(dict, 'assertDictEqual')
419 self.addTypeEqualityFunc(list, 'assertListEqual')
420 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
421 self.addTypeEqualityFunc(set, 'assertSetEqual')
422 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
423 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000424
425 def addTypeEqualityFunc(self, typeobj, function):
426 """Add a type specific assertEqual style function to compare a type.
427
428 This method is for use by TestCase subclasses that need to register
429 their own type equality functions to provide nicer error messages.
430
431 Args:
432 typeobj: The data type to call this function on when both values
433 are of the same type in assertEqual().
434 function: The callable taking two arguments and an optional
435 msg= argument that raises self.failureException with a
436 useful error message when the two arguments are not equal.
437 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000438 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000439
440 def addCleanup(self, function, *args, **kwargs):
441 """Add a function, with arguments, to be called when the test is
442 completed. Functions added are called on a LIFO basis and are
443 called after tearDown on test failure or success.
444
445 Cleanup items are called even if setUp fails (unlike tearDown)."""
446 self._cleanups.append((function, args, kwargs))
447
448 def setUp(self):
449 "Hook method for setting up the test fixture before exercising it."
450 pass
451
452 def tearDown(self):
453 "Hook method for deconstructing the test fixture after testing it."
454 pass
455
Benjamin Peterson847a4112010-03-14 15:04:17 +0000456 @classmethod
457 def setUpClass(cls):
458 "Hook method for setting up class fixture before running tests in the class."
459
460 @classmethod
461 def tearDownClass(cls):
462 "Hook method for deconstructing the class fixture after running all tests in the class."
463
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000464 def countTestCases(self):
465 return 1
466
467 def defaultTestResult(self):
468 return result.TestResult()
469
470 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000471 """Returns a one-line description of the test, or None if no
472 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000473
Michael Foord34c94622010-02-10 15:51:42 +0000474 The default implementation of this method returns the first line of
475 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000476 """
Michael Foord34c94622010-02-10 15:51:42 +0000477 doc = self._testMethodDoc
478 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000479
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000480
481 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000482 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000483
484 def __eq__(self, other):
485 if type(self) is not type(other):
486 return NotImplemented
487
488 return self._testMethodName == other._testMethodName
489
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000490 def __hash__(self):
491 return hash((type(self), self._testMethodName))
492
493 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000494 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000495
496 def __repr__(self):
497 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000498 (strclass(self.__class__), self._testMethodName)
499
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100500 def _addSkip(self, result, test_case, reason):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000501 addSkip = getattr(result, 'addSkip', None)
502 if addSkip is not None:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100503 addSkip(test_case, reason)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000504 else:
505 warnings.warn("TestResult has no addSkip method, skips not reported",
506 RuntimeWarning, 2)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100507 result.addSuccess(test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000508
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100509 @contextlib.contextmanager
Berker Peksag16ea19f2016-09-21 19:34:15 +0300510 def subTest(self, msg=_subtest_msg_sentinel, **params):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100511 """Return a context manager that will return the enclosed block
512 of code in a subtest identified by the optional message and
513 keyword parameters. A failure in the subtest marks the test
514 case as failed but resumes execution at the end of the enclosed
515 block, allowing further test code to be executed.
516 """
517 if not self._outcome.result_supports_subtests:
518 yield
519 return
520 parent = self._subtest
521 if parent is None:
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300522 params_map = _OrderedChainMap(params)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100523 else:
524 params_map = parent.params.new_child(params)
525 self._subtest = _SubTest(self, msg, params_map)
Michael Foordb3468f72010-12-19 03:19:47 +0000526 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100527 with self._outcome.testPartExecutor(self._subtest, isTest=True):
528 yield
529 if not self._outcome.success:
530 result = self._outcome.result
531 if result is not None and result.failfast:
532 raise _ShouldStop
533 elif self._outcome.expectedFailure:
534 # If the test is expecting a failure, we really want to
535 # stop now and register the expected failure.
536 raise _ShouldStop
537 finally:
538 self._subtest = parent
539
540 def _feedErrorsToResult(self, result, errors):
541 for test, exc_info in errors:
542 if isinstance(test, _SubTest):
543 result.addSubTest(test.test_case, test, exc_info)
544 elif exc_info is not None:
545 if issubclass(exc_info[0], self.failureException):
546 result.addFailure(test, exc_info)
547 else:
548 result.addError(test, exc_info)
549
550 def _addExpectedFailure(self, result, exc_info):
551 try:
552 addExpectedFailure = result.addExpectedFailure
553 except AttributeError:
554 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
555 RuntimeWarning)
556 result.addSuccess(self)
557 else:
558 addExpectedFailure(self, exc_info)
559
560 def _addUnexpectedSuccess(self, result):
561 try:
562 addUnexpectedSuccess = result.addUnexpectedSuccess
563 except AttributeError:
564 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
565 RuntimeWarning)
566 # We need to pass an actual exception and traceback to addFailure,
567 # otherwise the legacy result can choke.
568 try:
569 raise _UnexpectedSuccess from None
570 except _UnexpectedSuccess:
571 result.addFailure(self, sys.exc_info())
572 else:
573 addUnexpectedSuccess(self)
Michael Foordb3468f72010-12-19 03:19:47 +0000574
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000575 def run(self, result=None):
576 orig_result = result
577 if result is None:
578 result = self.defaultTestResult()
579 startTestRun = getattr(result, 'startTestRun', None)
580 if startTestRun is not None:
581 startTestRun()
582
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000583 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000584
585 testMethod = getattr(self, self._testMethodName)
586 if (getattr(self.__class__, "__unittest_skip__", False) or
587 getattr(testMethod, "__unittest_skip__", False)):
588 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000589 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000590 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
591 or getattr(testMethod, '__unittest_skip_why__', ''))
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100592 self._addSkip(result, self, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000593 finally:
594 result.stopTest(self)
595 return
Robert Collinsed599b72015-08-28 10:34:51 +1200596 expecting_failure_method = getattr(testMethod,
597 "__unittest_expecting_failure__", False)
598 expecting_failure_class = getattr(self,
599 "__unittest_expecting_failure__", False)
600 expecting_failure = expecting_failure_class or expecting_failure_method
Victor Stinner031bd532013-12-09 01:52:50 +0100601 outcome = _Outcome(result)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000602 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100603 self._outcome = outcome
Michael Foordb3468f72010-12-19 03:19:47 +0000604
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100605 with outcome.testPartExecutor(self):
606 self.setUp()
Michael Foordb3468f72010-12-19 03:19:47 +0000607 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100608 outcome.expecting_failure = expecting_failure
609 with outcome.testPartExecutor(self, isTest=True):
610 testMethod()
611 outcome.expecting_failure = False
612 with outcome.testPartExecutor(self):
613 self.tearDown()
Michael Foordb3468f72010-12-19 03:19:47 +0000614
615 self.doCleanups()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100616 for test, reason in outcome.skipped:
617 self._addSkip(result, test, reason)
618 self._feedErrorsToResult(result, outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +0000619 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100620 if expecting_failure:
621 if outcome.expectedFailure:
622 self._addExpectedFailure(result, outcome.expectedFailure)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000623 else:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100624 self._addUnexpectedSuccess(result)
625 else:
626 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400627 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000628 finally:
629 result.stopTest(self)
630 if orig_result is None:
631 stopTestRun = getattr(result, 'stopTestRun', None)
632 if stopTestRun is not None:
633 stopTestRun()
634
Victor Stinner031bd532013-12-09 01:52:50 +0100635 # explicitly break reference cycles:
636 # outcome.errors -> frame -> outcome -> outcome.errors
637 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
638 outcome.errors.clear()
639 outcome.expectedFailure = None
640
641 # clear the outcome, no more needed
642 self._outcome = None
643
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000644 def doCleanups(self):
645 """Execute all cleanup functions. Normally called for you after
646 tearDown."""
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100647 outcome = self._outcome or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000648 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000649 function, args, kwargs = self._cleanups.pop()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100650 with outcome.testPartExecutor(self):
651 function(*args, **kwargs)
Michael Foordb3468f72010-12-19 03:19:47 +0000652
653 # return this for backwards compatibility
654 # even though we no longer us it internally
655 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656
657 def __call__(self, *args, **kwds):
658 return self.run(*args, **kwds)
659
660 def debug(self):
661 """Run the test without collecting errors in a TestResult"""
662 self.setUp()
663 getattr(self, self._testMethodName)()
664 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000665 while self._cleanups:
666 function, args, kwargs = self._cleanups.pop(-1)
667 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000668
669 def skipTest(self, reason):
670 """Skip this test."""
671 raise SkipTest(reason)
672
673 def fail(self, msg=None):
674 """Fail immediately, with the given message."""
675 raise self.failureException(msg)
676
677 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000678 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000679 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000680 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000681 raise self.failureException(msg)
682
683 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000684 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000685 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000686 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000687 raise self.failureException(msg)
688
689 def _formatMessage(self, msg, standardMsg):
690 """Honour the longMessage attribute when generating failure messages.
691 If longMessage is False this means:
692 * Use only an explicit message if it is provided
693 * Otherwise use the standard message for the assert
694
695 If longMessage is True:
696 * Use the standard message
697 * If an explicit message is provided, plus ' : ' and the explicit message
698 """
699 if not self.longMessage:
700 return msg or standardMsg
701 if msg is None:
702 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000703 try:
704 # don't switch to '{}' formatting in Python 2.X
705 # it changes the way unicode input is handled
706 return '%s : %s' % (standardMsg, msg)
707 except UnicodeDecodeError:
708 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000709
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300710 def assertRaises(self, expected_exception, *args, **kwargs):
711 """Fail unless an exception of class expected_exception is raised
712 by the callable when invoked with specified positional and
713 keyword arguments. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200714 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000715 deemed to have suffered an error, exactly as for an
716 unexpected exception.
717
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300718 If called with the callable and arguments omitted, will return a
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000719 context object used like this::
720
Michael Foord1c42b122010-02-05 22:58:21 +0000721 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000722 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000723
Ezio Melottib4dc2502011-05-06 15:01:41 +0300724 An optional keyword argument 'msg' can be provided when assertRaises
725 is used as a context object.
726
Michael Foord1c42b122010-02-05 22:58:21 +0000727 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000728 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000729 exception after the assertion::
730
731 with self.assertRaises(SomeException) as cm:
732 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000733 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000734 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000735 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300736 context = _AssertRaisesContext(expected_exception, self)
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200737 try:
738 return context.handle('assertRaises', args, kwargs)
739 finally:
740 # bpo-23890: manually break a reference cycle
741 context = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000742
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300743 def assertWarns(self, expected_warning, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000744 """Fail unless a warning of class warnClass is triggered
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300745 by the callable when invoked with specified positional and
746 keyword arguments. If a different type of warning is
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000747 triggered, it will not be handled: depending on the other
748 warning filtering rules in effect, it might be silenced, printed
749 out, or raised as an exception.
750
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300751 If called with the callable and arguments omitted, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000752 context object used like this::
753
754 with self.assertWarns(SomeWarning):
755 do_something()
756
Ezio Melottib4dc2502011-05-06 15:01:41 +0300757 An optional keyword argument 'msg' can be provided when assertWarns
758 is used as a context object.
759
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000760 The context manager keeps a reference to the first matching
761 warning as the 'warning' attribute; similarly, the 'filename'
762 and 'lineno' attributes give you information about the line
763 of Python code from which the warning was triggered.
764 This allows you to inspect the warning after the assertion::
765
766 with self.assertWarns(SomeWarning) as cm:
767 do_something()
768 the_warning = cm.warning
769 self.assertEqual(the_warning.some_attribute, 147)
770 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300771 context = _AssertWarnsContext(expected_warning, self)
772 return context.handle('assertWarns', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000773
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200774 def assertLogs(self, logger=None, level=None):
775 """Fail unless a log message of level *level* or higher is emitted
776 on *logger_name* or its children. If omitted, *level* defaults to
777 INFO and *logger* defaults to the root logger.
778
779 This method must be used as a context manager, and will yield
780 a recording object with two attributes: `output` and `records`.
781 At the end of the context manager, the `output` attribute will
782 be a list of the matching formatted log messages and the
783 `records` attribute will be a list of the corresponding LogRecord
784 objects.
785
786 Example::
787
788 with self.assertLogs('foo', level='INFO') as cm:
789 logging.getLogger('foo').info('first message')
790 logging.getLogger('foo.bar').error('second message')
791 self.assertEqual(cm.output, ['INFO:foo:first message',
792 'ERROR:foo.bar:second message'])
793 """
794 return _AssertLogsContext(self, logger, level)
795
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000796 def _getAssertEqualityFunc(self, first, second):
797 """Get a detailed comparison function for the types of the two args.
798
799 Returns: A callable accepting (first, second, msg=None) that will
800 raise a failure exception if first != second with a useful human
801 readable error message for those types.
802 """
803 #
804 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
805 # and vice versa. I opted for the conservative approach in case
806 # subclasses are not intended to be compared in detail to their super
807 # class instances using a type equality func. This means testing
808 # subtypes won't automagically use the detailed comparison. Callers
809 # should use their type specific assertSpamEqual method to compare
810 # subclasses if the detailed comparison is desired and appropriate.
811 # See the discussion in http://bugs.python.org/issue2578.
812 #
813 if type(first) is type(second):
814 asserter = self._type_equality_funcs.get(type(first))
815 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500816 if isinstance(asserter, str):
817 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000818 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000819
820 return self._baseAssertEqual
821
822 def _baseAssertEqual(self, first, second, msg=None):
823 """The default assertEqual implementation, not type specific."""
824 if not first == second:
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300825 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000826 msg = self._formatMessage(msg, standardMsg)
827 raise self.failureException(msg)
828
829 def assertEqual(self, first, second, msg=None):
830 """Fail if the two objects are unequal as determined by the '=='
831 operator.
832 """
833 assertion_func = self._getAssertEqualityFunc(first, second)
834 assertion_func(first, second, msg=msg)
835
836 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200837 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000838 operator.
839 """
840 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000841 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
842 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000843 raise self.failureException(msg)
844
Michael Foord321d0592010-11-02 13:44:51 +0000845 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000846 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000847 """Fail if the two objects are unequal as determined by their
848 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000849 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300850 difference between the two objects is more than the given
851 delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000852
853 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000854 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000855
856 If the two objects compare equal then they will automatically
857 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000858 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000859 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000860 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000861 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000862 if delta is not None and places is not None:
863 raise TypeError("specify delta or places not both")
864
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200865 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000866 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200867 if diff <= delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000868 return
869
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200870 standardMsg = '%s != %s within %s delta (%s difference)' % (
871 safe_repr(first),
872 safe_repr(second),
873 safe_repr(delta),
874 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000875 else:
876 if places is None:
877 places = 7
878
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200879 if round(diff, places) == 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000880 return
881
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200882 standardMsg = '%s != %s within %r places (%s difference)' % (
883 safe_repr(first),
884 safe_repr(second),
885 places,
886 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000887 msg = self._formatMessage(msg, standardMsg)
888 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000889
Michael Foord321d0592010-11-02 13:44:51 +0000890 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000891 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000892 """Fail if the two objects are equal as determined by their
893 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000894 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300895 difference between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000896
897 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000898 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000899
900 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000901 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000902 if delta is not None and places is not None:
903 raise TypeError("specify delta or places not both")
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200904 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000905 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200906 if not (first == second) and diff > delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000907 return
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200908 standardMsg = '%s == %s within %s delta (%s difference)' % (
909 safe_repr(first),
910 safe_repr(second),
911 safe_repr(delta),
912 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000913 else:
914 if places is None:
915 places = 7
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200916 if not (first == second) and round(diff, places) != 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000917 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000918 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000919 safe_repr(second),
920 places)
921
922 msg = self._formatMessage(msg, standardMsg)
923 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000924
Michael Foord085dfd32010-06-05 12:17:02 +0000925 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000926 """An equality assertion for ordered sequences (like lists and tuples).
927
R. David Murrayad13f222010-01-29 22:17:58 +0000928 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000929 which can be indexed, has a length, and has an equality operator.
930
931 Args:
932 seq1: The first sequence to compare.
933 seq2: The second sequence to compare.
934 seq_type: The expected datatype of the sequences, or None if no
935 datatype should be enforced.
936 msg: Optional message to use on failure instead of a list of
937 differences.
938 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400939 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000940 seq_type_name = seq_type.__name__
941 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000942 raise self.failureException('First sequence is not a %s: %s'
943 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000944 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000945 raise self.failureException('Second sequence is not a %s: %s'
946 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000947 else:
948 seq_type_name = "sequence"
949
950 differing = None
951 try:
952 len1 = len(seq1)
953 except (TypeError, NotImplementedError):
954 differing = 'First %s has no length. Non-sequence?' % (
955 seq_type_name)
956
957 if differing is None:
958 try:
959 len2 = len(seq2)
960 except (TypeError, NotImplementedError):
961 differing = 'Second %s has no length. Non-sequence?' % (
962 seq_type_name)
963
964 if differing is None:
965 if seq1 == seq2:
966 return
967
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300968 differing = '%ss differ: %s != %s\n' % (
969 (seq_type_name.capitalize(),) +
970 _common_shorten_repr(seq1, seq2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000971
972 for i in range(min(len1, len2)):
973 try:
974 item1 = seq1[i]
975 except (TypeError, IndexError, NotImplementedError):
976 differing += ('\nUnable to index element %d of first %s\n' %
977 (i, seq_type_name))
978 break
979
980 try:
981 item2 = seq2[i]
982 except (TypeError, IndexError, NotImplementedError):
983 differing += ('\nUnable to index element %d of second %s\n' %
984 (i, seq_type_name))
985 break
986
987 if item1 != item2:
988 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +0300989 ((i,) + _common_shorten_repr(item1, item2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000990 break
991 else:
992 if (len1 == len2 and seq_type is None and
993 type(seq1) != type(seq2)):
994 # The sequences are the same, but have differing types.
995 return
996
997 if len1 > len2:
998 differing += ('\nFirst %s contains %d additional '
999 'elements.\n' % (seq_type_name, len1 - len2))
1000 try:
1001 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001002 (len2, safe_repr(seq1[len2])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001003 except (TypeError, IndexError, NotImplementedError):
1004 differing += ('Unable to index element %d '
1005 'of first %s\n' % (len2, seq_type_name))
1006 elif len1 < len2:
1007 differing += ('\nSecond %s contains %d additional '
1008 'elements.\n' % (seq_type_name, len2 - len1))
1009 try:
1010 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001011 (len1, safe_repr(seq2[len1])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001012 except (TypeError, IndexError, NotImplementedError):
1013 differing += ('Unable to index element %d '
1014 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +00001015 standardMsg = differing
1016 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001017 difflib.ndiff(pprint.pformat(seq1).splitlines(),
1018 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +00001019
1020 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001021 msg = self._formatMessage(msg, standardMsg)
1022 self.fail(msg)
1023
Michael Foord085dfd32010-06-05 12:17:02 +00001024 def _truncateMessage(self, message, diff):
1025 max_diff = self.maxDiff
1026 if max_diff is None or len(diff) <= max_diff:
1027 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +00001028 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +00001029
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001030 def assertListEqual(self, list1, list2, msg=None):
1031 """A list-specific equality assertion.
1032
1033 Args:
1034 list1: The first list to compare.
1035 list2: The second list to compare.
1036 msg: Optional message to use on failure instead of a list of
1037 differences.
1038
1039 """
1040 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
1041
1042 def assertTupleEqual(self, tuple1, tuple2, msg=None):
1043 """A tuple-specific equality assertion.
1044
1045 Args:
1046 tuple1: The first tuple to compare.
1047 tuple2: The second tuple to compare.
1048 msg: Optional message to use on failure instead of a list of
1049 differences.
1050 """
1051 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1052
1053 def assertSetEqual(self, set1, set2, msg=None):
1054 """A set-specific equality assertion.
1055
1056 Args:
1057 set1: The first set to compare.
1058 set2: The second set to compare.
1059 msg: Optional message to use on failure instead of a list of
1060 differences.
1061
Michael Foord91c9da32010-03-20 17:21:27 +00001062 assertSetEqual uses ducktyping to support different types of sets, and
1063 is optimized for sets specifically (parameters must support a
1064 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001065 """
1066 try:
1067 difference1 = set1.difference(set2)
1068 except TypeError as e:
1069 self.fail('invalid type when attempting set difference: %s' % e)
1070 except AttributeError as e:
1071 self.fail('first argument does not support set difference: %s' % e)
1072
1073 try:
1074 difference2 = set2.difference(set1)
1075 except TypeError as e:
1076 self.fail('invalid type when attempting set difference: %s' % e)
1077 except AttributeError as e:
1078 self.fail('second argument does not support set difference: %s' % e)
1079
1080 if not (difference1 or difference2):
1081 return
1082
1083 lines = []
1084 if difference1:
1085 lines.append('Items in the first set but not the second:')
1086 for item in difference1:
1087 lines.append(repr(item))
1088 if difference2:
1089 lines.append('Items in the second set but not the first:')
1090 for item in difference2:
1091 lines.append(repr(item))
1092
1093 standardMsg = '\n'.join(lines)
1094 self.fail(self._formatMessage(msg, standardMsg))
1095
1096 def assertIn(self, member, container, msg=None):
1097 """Just like self.assertTrue(a in b), but with a nicer default message."""
1098 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001099 standardMsg = '%s not found in %s' % (safe_repr(member),
1100 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001101 self.fail(self._formatMessage(msg, standardMsg))
1102
1103 def assertNotIn(self, member, container, msg=None):
1104 """Just like self.assertTrue(a not in b), but with a nicer default message."""
1105 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001106 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1107 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001108 self.fail(self._formatMessage(msg, standardMsg))
1109
1110 def assertIs(self, expr1, expr2, msg=None):
1111 """Just like self.assertTrue(a is b), but with a nicer default message."""
1112 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001113 standardMsg = '%s is not %s' % (safe_repr(expr1),
1114 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001115 self.fail(self._formatMessage(msg, standardMsg))
1116
1117 def assertIsNot(self, expr1, expr2, msg=None):
1118 """Just like self.assertTrue(a is not b), but with a nicer default message."""
1119 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001120 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001121 self.fail(self._formatMessage(msg, standardMsg))
1122
1123 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001124 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1125 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001126
1127 if d1 != d2:
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001128 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
Michael Foord085dfd32010-06-05 12:17:02 +00001129 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001130 pprint.pformat(d1).splitlines(),
1131 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +00001132 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001133 self.fail(self._formatMessage(msg, standardMsg))
1134
Ezio Melotti0f535012011-04-03 18:02:13 +03001135 def assertDictContainsSubset(self, subset, dictionary, msg=None):
1136 """Checks whether dictionary is a superset of subset."""
1137 warnings.warn('assertDictContainsSubset is deprecated',
1138 DeprecationWarning)
1139 missing = []
1140 mismatched = []
1141 for key, value in subset.items():
1142 if key not in dictionary:
1143 missing.append(key)
1144 elif value != dictionary[key]:
1145 mismatched.append('%s, expected: %s, actual: %s' %
1146 (safe_repr(key), safe_repr(value),
1147 safe_repr(dictionary[key])))
1148
1149 if not (missing or mismatched):
1150 return
1151
1152 standardMsg = ''
1153 if missing:
1154 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1155 missing)
1156 if mismatched:
1157 if standardMsg:
1158 standardMsg += '; '
1159 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1160
1161 self.fail(self._formatMessage(msg, standardMsg))
1162
1163
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001164 def assertCountEqual(self, first, second, msg=None):
1165 """An unordered sequence comparison asserting that the same elements,
1166 regardless of order. If the same element occurs more than once,
1167 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001168
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001169 self.assertEqual(Counter(list(first)),
1170 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001171
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001172 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001173 - [0, 1, 1] and [1, 0, 1] compare equal.
1174 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001175
Michael Foord8442a602010-03-20 16:58:04 +00001176 """
Michael Foorde180d392011-01-28 19:51:48 +00001177 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001178 try:
Michael Foorde180d392011-01-28 19:51:48 +00001179 first = collections.Counter(first_seq)
1180 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001181 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001182 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001183 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001184 else:
Michael Foorde180d392011-01-28 19:51:48 +00001185 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001186 return
Michael Foorde180d392011-01-28 19:51:48 +00001187 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001188
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001189 if differences:
1190 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001191 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001192 diffMsg = '\n'.join(lines)
1193 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1194 msg = self._formatMessage(msg, standardMsg)
1195 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001196
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001197 def assertMultiLineEqual(self, first, second, msg=None):
1198 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001199 self.assertIsInstance(first, str, 'First argument is not a string')
1200 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001201
1202 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001203 # don't use difflib if the strings are too long
1204 if (len(first) > self._diffThreshold or
1205 len(second) > self._diffThreshold):
1206 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001207 firstlines = first.splitlines(keepends=True)
1208 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001209 if len(firstlines) == 1 and first.strip('\r\n') == first:
1210 firstlines = [first + '\n']
1211 secondlines = [second + '\n']
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001212 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Michael Foordc653ce32010-07-10 13:52:22 +00001213 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001214 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001215 self.fail(self._formatMessage(msg, standardMsg))
1216
1217 def assertLess(self, a, b, msg=None):
1218 """Just like self.assertTrue(a < b), but with a nicer default message."""
1219 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001220 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001221 self.fail(self._formatMessage(msg, standardMsg))
1222
1223 def assertLessEqual(self, a, b, msg=None):
1224 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1225 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001226 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001227 self.fail(self._formatMessage(msg, standardMsg))
1228
1229 def assertGreater(self, a, b, msg=None):
1230 """Just like self.assertTrue(a > b), but with a nicer default message."""
1231 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001232 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001233 self.fail(self._formatMessage(msg, standardMsg))
1234
1235 def assertGreaterEqual(self, a, b, msg=None):
1236 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1237 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001238 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001239 self.fail(self._formatMessage(msg, standardMsg))
1240
1241 def assertIsNone(self, obj, msg=None):
1242 """Same as self.assertTrue(obj is None), with a nicer default message."""
1243 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001244 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001245 self.fail(self._formatMessage(msg, standardMsg))
1246
1247 def assertIsNotNone(self, obj, msg=None):
1248 """Included for symmetry with assertIsNone."""
1249 if obj is None:
1250 standardMsg = 'unexpectedly None'
1251 self.fail(self._formatMessage(msg, standardMsg))
1252
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001253 def assertIsInstance(self, obj, cls, msg=None):
1254 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1255 default message."""
1256 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001257 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001258 self.fail(self._formatMessage(msg, standardMsg))
1259
1260 def assertNotIsInstance(self, obj, cls, msg=None):
1261 """Included for symmetry with assertIsInstance."""
1262 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001263 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001264 self.fail(self._formatMessage(msg, standardMsg))
1265
Ezio Melottied3a7d22010-12-01 02:32:32 +00001266 def assertRaisesRegex(self, expected_exception, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001267 *args, **kwargs):
Ezio Melottied3a7d22010-12-01 02:32:32 +00001268 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001269
1270 Args:
1271 expected_exception: Exception class expected to be raised.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001272 expected_regex: Regex (re.Pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001273 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001274 args: Function to be called and extra positional args.
1275 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001276 msg: Optional message used in case of failure. Can only be used
1277 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001278 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001279 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1280 return context.handle('assertRaisesRegex', args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001281
Ezio Melottied3a7d22010-12-01 02:32:32 +00001282 def assertWarnsRegex(self, expected_warning, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001283 *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001284 """Asserts that the message in a triggered warning matches a regexp.
1285 Basic functioning is similar to assertWarns() with the addition
1286 that only warnings whose messages also match the regular expression
1287 are considered successful matches.
1288
1289 Args:
1290 expected_warning: Warning class expected to be triggered.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001291 expected_regex: Regex (re.Pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001292 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001293 args: Function to be called and extra positional args.
1294 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001295 msg: Optional message used in case of failure. Can only be used
1296 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001297 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001298 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1299 return context.handle('assertWarnsRegex', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001300
Ezio Melottied3a7d22010-12-01 02:32:32 +00001301 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001302 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001303 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001304 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001305 expected_regex = re.compile(expected_regex)
1306 if not expected_regex.search(text):
Robert Collinsbe6caca2015-08-20 11:13:09 +12001307 standardMsg = "Regex didn't match: %r not found in %r" % (
1308 expected_regex.pattern, text)
1309 # _formatMessage ensures the longMessage option is respected
1310 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001311 raise self.failureException(msg)
1312
Ezio Melotti8f776302010-12-10 02:32:05 +00001313 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001314 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001315 if isinstance(unexpected_regex, (str, bytes)):
1316 unexpected_regex = re.compile(unexpected_regex)
1317 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001318 if match:
Robert Collinsbe6caca2015-08-20 11:13:09 +12001319 standardMsg = 'Regex matched: %r matches %r in %r' % (
1320 text[match.start() : match.end()],
1321 unexpected_regex.pattern,
1322 text)
1323 # _formatMessage ensures the longMessage option is respected
1324 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001325 raise self.failureException(msg)
1326
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001327
Ezio Melottied3a7d22010-12-01 02:32:32 +00001328 def _deprecate(original_func):
1329 def deprecated_func(*args, **kwargs):
1330 warnings.warn(
1331 'Please use {0} instead.'.format(original_func.__name__),
1332 DeprecationWarning, 2)
1333 return original_func(*args, **kwargs)
1334 return deprecated_func
1335
Ezio Melotti361467e2011-04-03 17:37:58 +03001336 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001337 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1338 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1339 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1340 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1341 failUnless = assert_ = _deprecate(assertTrue)
1342 failUnlessRaises = _deprecate(assertRaises)
1343 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001344 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1345 assertRegexpMatches = _deprecate(assertRegex)
Robert Collinsbe6caca2015-08-20 11:13:09 +12001346 assertNotRegexpMatches = _deprecate(assertNotRegex)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001347
1348
1349
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001350class FunctionTestCase(TestCase):
1351 """A test case that wraps a test function.
1352
1353 This is useful for slipping pre-existing test functions into the
1354 unittest framework. Optionally, set-up and tidy-up functions can be
1355 supplied. As with TestCase, the tidy-up ('tearDown') function will
1356 always be called if the set-up ('setUp') function ran successfully.
1357 """
1358
1359 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1360 super(FunctionTestCase, self).__init__()
1361 self._setUpFunc = setUp
1362 self._tearDownFunc = tearDown
1363 self._testFunc = testFunc
1364 self._description = description
1365
1366 def setUp(self):
1367 if self._setUpFunc is not None:
1368 self._setUpFunc()
1369
1370 def tearDown(self):
1371 if self._tearDownFunc is not None:
1372 self._tearDownFunc()
1373
1374 def runTest(self):
1375 self._testFunc()
1376
1377 def id(self):
1378 return self._testFunc.__name__
1379
1380 def __eq__(self, other):
1381 if not isinstance(other, self.__class__):
1382 return NotImplemented
1383
1384 return self._setUpFunc == other._setUpFunc and \
1385 self._tearDownFunc == other._tearDownFunc and \
1386 self._testFunc == other._testFunc and \
1387 self._description == other._description
1388
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001389 def __hash__(self):
1390 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1391 self._testFunc, self._description))
1392
1393 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001394 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001395 self._testFunc.__name__)
1396
1397 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001398 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001399 self._testFunc)
1400
1401 def shortDescription(self):
1402 if self._description is not None:
1403 return self._description
1404 doc = self._testFunc.__doc__
1405 return doc and doc.split("\n")[0].strip() or None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001406
1407
1408class _SubTest(TestCase):
1409
1410 def __init__(self, test_case, message, params):
1411 super().__init__()
1412 self._message = message
1413 self.test_case = test_case
1414 self.params = params
1415 self.failureException = test_case.failureException
1416
1417 def runTest(self):
1418 raise NotImplementedError("subtests cannot be run directly")
1419
1420 def _subDescription(self):
1421 parts = []
Berker Peksag16ea19f2016-09-21 19:34:15 +03001422 if self._message is not _subtest_msg_sentinel:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001423 parts.append("[{}]".format(self._message))
1424 if self.params:
1425 params_desc = ', '.join(
1426 "{}={!r}".format(k, v)
Serhiy Storchaka48fbe522017-06-23 21:47:39 +03001427 for (k, v) in self.params.items())
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001428 parts.append("({})".format(params_desc))
1429 return " ".join(parts) or '(<subtest>)'
1430
1431 def id(self):
1432 return "{} {}".format(self.test_case.id(), self._subDescription())
1433
1434 def shortDescription(self):
1435 """Returns a one-line description of the subtest, or None if no
1436 description has been provided.
1437 """
1438 return self.test_case.shortDescription()
1439
1440 def __str__(self):
1441 return "{} {}".format(self.test_case, self._subDescription())