blob: 811f5df23dd14a92b5cd21623b2d4e65da05a3c9 [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))
160 if args and args[0] is None:
161 warnings.warn("callable is None",
162 DeprecationWarning, 3)
163 args = ()
164 if not args:
165 self.msg = kwargs.pop('msg', None)
166 if kwargs:
167 warnings.warn('%r is an invalid keyword argument for '
168 'this function' % next(iter(kwargs)),
169 DeprecationWarning, 3)
170 return self
171
172 callable_obj, *args = args
173 try:
174 self.obj_name = callable_obj.__name__
175 except AttributeError:
176 self.obj_name = str(callable_obj)
177 with self:
178 callable_obj(*args, **kwargs)
179 finally:
180 # bpo-23890: manually break a reference cycle
181 self = None
Ezio Melottib4dc2502011-05-06 15:01:41 +0300182
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000183
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000184class _AssertRaisesContext(_AssertRaisesBaseContext):
185 """A context manager used to implement TestCase.assertRaises* methods."""
186
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300187 _base_type = BaseException
188 _base_type_str = 'an exception type or tuple of exception types'
189
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000190 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000191 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000192
193 def __exit__(self, exc_type, exc_value, tb):
194 if exc_type is None:
195 try:
196 exc_name = self.expected.__name__
197 except AttributeError:
198 exc_name = str(self.expected)
199 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300200 self._raiseFailure("{} not raised by {}".format(exc_name,
201 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000202 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300203 self._raiseFailure("{} not raised".format(exc_name))
Antoine Pitrou96810222014-04-29 01:23:50 +0200204 else:
205 traceback.clear_frames(tb)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000206 if not issubclass(exc_type, self.expected):
207 # let unexpected exceptions pass through
208 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000209 # store exception, without traceback, for later retrieval
210 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000211 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000212 return True
213
Ezio Melottied3a7d22010-12-01 02:32:32 +0000214 expected_regex = self.expected_regex
215 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300216 self._raiseFailure('"{}" does not match "{}"'.format(
217 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000218 return True
219
220
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000221class _AssertWarnsContext(_AssertRaisesBaseContext):
222 """A context manager used to implement TestCase.assertWarns* methods."""
223
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300224 _base_type = Warning
225 _base_type_str = 'a warning type or tuple of warning types'
226
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000227 def __enter__(self):
228 # The __warningregistry__'s need to be in a pristine state for tests
229 # to work properly.
230 for v in sys.modules.values():
231 if getattr(v, '__warningregistry__', None):
232 v.__warningregistry__ = {}
233 self.warnings_manager = warnings.catch_warnings(record=True)
234 self.warnings = self.warnings_manager.__enter__()
235 warnings.simplefilter("always", self.expected)
236 return self
237
238 def __exit__(self, exc_type, exc_value, tb):
239 self.warnings_manager.__exit__(exc_type, exc_value, tb)
240 if exc_type is not None:
241 # let unexpected exceptions pass through
242 return
243 try:
244 exc_name = self.expected.__name__
245 except AttributeError:
246 exc_name = str(self.expected)
247 first_matching = None
248 for m in self.warnings:
249 w = m.message
250 if not isinstance(w, self.expected):
251 continue
252 if first_matching is None:
253 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000254 if (self.expected_regex is not None and
255 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000256 continue
257 # store warning for later retrieval
258 self.warning = w
259 self.filename = m.filename
260 self.lineno = m.lineno
261 return
262 # Now we simply try to choose a helpful failure message
263 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300264 self._raiseFailure('"{}" does not match "{}"'.format(
265 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000266 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300267 self._raiseFailure("{} not triggered by {}".format(exc_name,
268 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000269 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300270 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000271
272
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200273
274_LoggingWatcher = collections.namedtuple("_LoggingWatcher",
275 ["records", "output"])
276
277
278class _CapturingHandler(logging.Handler):
279 """
280 A logging handler capturing all (raw and formatted) logging output.
281 """
282
283 def __init__(self):
284 logging.Handler.__init__(self)
285 self.watcher = _LoggingWatcher([], [])
286
287 def flush(self):
288 pass
289
290 def emit(self, record):
291 self.watcher.records.append(record)
292 msg = self.format(record)
293 self.watcher.output.append(msg)
294
295
296
297class _AssertLogsContext(_BaseTestCaseContext):
298 """A context manager used to implement TestCase.assertLogs()."""
299
300 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
301
302 def __init__(self, test_case, logger_name, level):
303 _BaseTestCaseContext.__init__(self, test_case)
304 self.logger_name = logger_name
305 if level:
306 self.level = logging._nameToLevel.get(level, level)
307 else:
308 self.level = logging.INFO
309 self.msg = None
310
311 def __enter__(self):
312 if isinstance(self.logger_name, logging.Logger):
313 logger = self.logger = self.logger_name
314 else:
315 logger = self.logger = logging.getLogger(self.logger_name)
316 formatter = logging.Formatter(self.LOGGING_FORMAT)
317 handler = _CapturingHandler()
318 handler.setFormatter(formatter)
319 self.watcher = handler.watcher
320 self.old_handlers = logger.handlers[:]
321 self.old_level = logger.level
322 self.old_propagate = logger.propagate
323 logger.handlers = [handler]
324 logger.setLevel(self.level)
325 logger.propagate = False
326 return handler.watcher
327
328 def __exit__(self, exc_type, exc_value, tb):
329 self.logger.handlers = self.old_handlers
330 self.logger.propagate = self.old_propagate
331 self.logger.setLevel(self.old_level)
332 if exc_type is not None:
333 # let unexpected exceptions pass through
334 return False
335 if len(self.watcher.records) == 0:
336 self._raiseFailure(
337 "no logs of level {} or higher triggered on {}"
338 .format(logging.getLevelName(self.level), self.logger.name))
339
340
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300341class _OrderedChainMap(collections.ChainMap):
342 def __iter__(self):
343 seen = set()
344 for mapping in self.maps:
345 for k in mapping:
346 if k not in seen:
347 seen.add(k)
348 yield k
349
350
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000351class TestCase(object):
352 """A class whose instances are single test cases.
353
354 By default, the test code itself should be placed in a method named
355 'runTest'.
356
357 If the fixture may be used for many test cases, create as
358 many test methods as are needed. When instantiating such a TestCase
359 subclass, specify in the constructor arguments the name of the test method
360 that the instance is to execute.
361
362 Test authors should subclass TestCase for their own tests. Construction
363 and deconstruction of the test's environment ('fixture') can be
364 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
365
366 If it is necessary to override the __init__ method, the base class
367 __init__ method must always be called. It is important that subclasses
368 should not change the signature of their __init__ method, since instances
369 of the classes are instantiated automatically by parts of the framework
370 in order to be run.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000371
Ezio Melotti31797e52013-03-29 03:42:29 +0200372 When subclassing TestCase, you can set these attributes:
373 * failureException: determines which exception will be raised when
374 the instance's assertion methods fail; test methods raising this
375 exception will be deemed to have 'failed' rather than 'errored'.
376 * longMessage: determines whether long messages (including repr of
377 objects used in assert methods) will be printed on failure in *addition*
378 to any explicit message passed.
379 * maxDiff: sets the maximum length of a diff in failure messages
380 by assert methods using difflib. It is looked up as an instance
381 attribute so can be configured by individual tests if required.
382 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000383
384 failureException = AssertionError
385
Michael Foord5074df62010-12-03 00:53:09 +0000386 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000387
Michael Foord085dfd32010-06-05 12:17:02 +0000388 maxDiff = 80*8
389
Ezio Melottiedd117f2011-04-27 10:20:38 +0300390 # If a string is longer than _diffThreshold, use normal comparison instead
391 # of difflib. See #11763.
392 _diffThreshold = 2**16
393
Benjamin Peterson847a4112010-03-14 15:04:17 +0000394 # Attribute used by TestSuite for classSetUp
395
396 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000397
398 def __init__(self, methodName='runTest'):
399 """Create an instance of the class that will use the named test
400 method when executed. Raises a ValueError if the instance does
401 not have a method with the specified name.
402 """
403 self._testMethodName = methodName
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100404 self._outcome = None
Michael Foord32e1d832011-01-03 17:00:11 +0000405 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000406 try:
407 testMethod = getattr(self, methodName)
408 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000409 if methodName != 'runTest':
410 # we allow instantiation with no explicit method name
411 # but not an *incorrect* or missing method name
412 raise ValueError("no such test method in %s: %s" %
413 (self.__class__, methodName))
414 else:
415 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000416 self._cleanups = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100417 self._subtest = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000418
419 # Map types to custom assertEqual functions that will compare
420 # instances of said type in more detail to generate a more useful
421 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500422 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000423 self.addTypeEqualityFunc(dict, 'assertDictEqual')
424 self.addTypeEqualityFunc(list, 'assertListEqual')
425 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
426 self.addTypeEqualityFunc(set, 'assertSetEqual')
427 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
428 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000429
430 def addTypeEqualityFunc(self, typeobj, function):
431 """Add a type specific assertEqual style function to compare a type.
432
433 This method is for use by TestCase subclasses that need to register
434 their own type equality functions to provide nicer error messages.
435
436 Args:
437 typeobj: The data type to call this function on when both values
438 are of the same type in assertEqual().
439 function: The callable taking two arguments and an optional
440 msg= argument that raises self.failureException with a
441 useful error message when the two arguments are not equal.
442 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000443 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000444
Serhiy Storchakaa37f3562019-04-01 10:59:24 +0300445 def addCleanup(*args, **kwargs):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000446 """Add a function, with arguments, to be called when the test is
447 completed. Functions added are called on a LIFO basis and are
448 called after tearDown on test failure or success.
449
450 Cleanup items are called even if setUp fails (unlike tearDown)."""
Serhiy Storchakaa37f3562019-04-01 10:59:24 +0300451 if len(args) >= 2:
452 self, function, *args = args
453 elif not args:
454 raise TypeError("descriptor 'addCleanup' of 'TestCase' object "
455 "needs an argument")
456 elif 'function' in kwargs:
457 function = kwargs.pop('function')
458 self, *args = args
459 else:
460 raise TypeError('addCleanup expected at least 1 positional '
461 'argument, got %d' % (len(args)-1))
462 args = tuple(args)
463
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000464 self._cleanups.append((function, args, kwargs))
465
466 def setUp(self):
467 "Hook method for setting up the test fixture before exercising it."
468 pass
469
470 def tearDown(self):
471 "Hook method for deconstructing the test fixture after testing it."
472 pass
473
Benjamin Peterson847a4112010-03-14 15:04:17 +0000474 @classmethod
475 def setUpClass(cls):
476 "Hook method for setting up class fixture before running tests in the class."
477
478 @classmethod
479 def tearDownClass(cls):
480 "Hook method for deconstructing the class fixture after running all tests in the class."
481
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000482 def countTestCases(self):
483 return 1
484
485 def defaultTestResult(self):
486 return result.TestResult()
487
488 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000489 """Returns a one-line description of the test, or None if no
490 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000491
Michael Foord34c94622010-02-10 15:51:42 +0000492 The default implementation of this method returns the first line of
493 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000494 """
Michael Foord34c94622010-02-10 15:51:42 +0000495 doc = self._testMethodDoc
496 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000497
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000498
499 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000500 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000501
502 def __eq__(self, other):
503 if type(self) is not type(other):
504 return NotImplemented
505
506 return self._testMethodName == other._testMethodName
507
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000508 def __hash__(self):
509 return hash((type(self), self._testMethodName))
510
511 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000512 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000513
514 def __repr__(self):
515 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000516 (strclass(self.__class__), self._testMethodName)
517
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100518 def _addSkip(self, result, test_case, reason):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000519 addSkip = getattr(result, 'addSkip', None)
520 if addSkip is not None:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100521 addSkip(test_case, reason)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000522 else:
523 warnings.warn("TestResult has no addSkip method, skips not reported",
524 RuntimeWarning, 2)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100525 result.addSuccess(test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000526
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100527 @contextlib.contextmanager
Berker Peksag16ea19f2016-09-21 19:34:15 +0300528 def subTest(self, msg=_subtest_msg_sentinel, **params):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100529 """Return a context manager that will return the enclosed block
530 of code in a subtest identified by the optional message and
531 keyword parameters. A failure in the subtest marks the test
532 case as failed but resumes execution at the end of the enclosed
533 block, allowing further test code to be executed.
534 """
Miss Islington (bot)7a98e302018-10-12 04:07:01 -0700535 if self._outcome is None or not self._outcome.result_supports_subtests:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100536 yield
537 return
538 parent = self._subtest
539 if parent is None:
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300540 params_map = _OrderedChainMap(params)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100541 else:
542 params_map = parent.params.new_child(params)
543 self._subtest = _SubTest(self, msg, params_map)
Michael Foordb3468f72010-12-19 03:19:47 +0000544 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100545 with self._outcome.testPartExecutor(self._subtest, isTest=True):
546 yield
547 if not self._outcome.success:
548 result = self._outcome.result
549 if result is not None and result.failfast:
550 raise _ShouldStop
551 elif self._outcome.expectedFailure:
552 # If the test is expecting a failure, we really want to
553 # stop now and register the expected failure.
554 raise _ShouldStop
555 finally:
556 self._subtest = parent
557
558 def _feedErrorsToResult(self, result, errors):
559 for test, exc_info in errors:
560 if isinstance(test, _SubTest):
561 result.addSubTest(test.test_case, test, exc_info)
562 elif exc_info is not None:
563 if issubclass(exc_info[0], self.failureException):
564 result.addFailure(test, exc_info)
565 else:
566 result.addError(test, exc_info)
567
568 def _addExpectedFailure(self, result, exc_info):
569 try:
570 addExpectedFailure = result.addExpectedFailure
571 except AttributeError:
572 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
573 RuntimeWarning)
574 result.addSuccess(self)
575 else:
576 addExpectedFailure(self, exc_info)
577
578 def _addUnexpectedSuccess(self, result):
579 try:
580 addUnexpectedSuccess = result.addUnexpectedSuccess
581 except AttributeError:
582 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
583 RuntimeWarning)
584 # We need to pass an actual exception and traceback to addFailure,
585 # otherwise the legacy result can choke.
586 try:
587 raise _UnexpectedSuccess from None
588 except _UnexpectedSuccess:
589 result.addFailure(self, sys.exc_info())
590 else:
591 addUnexpectedSuccess(self)
Michael Foordb3468f72010-12-19 03:19:47 +0000592
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000593 def run(self, result=None):
594 orig_result = result
595 if result is None:
596 result = self.defaultTestResult()
597 startTestRun = getattr(result, 'startTestRun', None)
598 if startTestRun is not None:
599 startTestRun()
600
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000601 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000602
603 testMethod = getattr(self, self._testMethodName)
604 if (getattr(self.__class__, "__unittest_skip__", False) or
605 getattr(testMethod, "__unittest_skip__", False)):
606 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000607 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000608 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
609 or getattr(testMethod, '__unittest_skip_why__', ''))
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100610 self._addSkip(result, self, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000611 finally:
612 result.stopTest(self)
613 return
Robert Collinsed599b72015-08-28 10:34:51 +1200614 expecting_failure_method = getattr(testMethod,
615 "__unittest_expecting_failure__", False)
616 expecting_failure_class = getattr(self,
617 "__unittest_expecting_failure__", False)
618 expecting_failure = expecting_failure_class or expecting_failure_method
Victor Stinner031bd532013-12-09 01:52:50 +0100619 outcome = _Outcome(result)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000620 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100621 self._outcome = outcome
Michael Foordb3468f72010-12-19 03:19:47 +0000622
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100623 with outcome.testPartExecutor(self):
624 self.setUp()
Michael Foordb3468f72010-12-19 03:19:47 +0000625 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100626 outcome.expecting_failure = expecting_failure
627 with outcome.testPartExecutor(self, isTest=True):
628 testMethod()
629 outcome.expecting_failure = False
630 with outcome.testPartExecutor(self):
631 self.tearDown()
Michael Foordb3468f72010-12-19 03:19:47 +0000632
633 self.doCleanups()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100634 for test, reason in outcome.skipped:
635 self._addSkip(result, test, reason)
636 self._feedErrorsToResult(result, outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +0000637 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100638 if expecting_failure:
639 if outcome.expectedFailure:
640 self._addExpectedFailure(result, outcome.expectedFailure)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000641 else:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100642 self._addUnexpectedSuccess(result)
643 else:
644 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400645 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000646 finally:
647 result.stopTest(self)
648 if orig_result is None:
649 stopTestRun = getattr(result, 'stopTestRun', None)
650 if stopTestRun is not None:
651 stopTestRun()
652
Victor Stinner031bd532013-12-09 01:52:50 +0100653 # explicitly break reference cycles:
654 # outcome.errors -> frame -> outcome -> outcome.errors
655 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
656 outcome.errors.clear()
657 outcome.expectedFailure = None
658
659 # clear the outcome, no more needed
660 self._outcome = None
661
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000662 def doCleanups(self):
663 """Execute all cleanup functions. Normally called for you after
664 tearDown."""
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100665 outcome = self._outcome or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000666 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000667 function, args, kwargs = self._cleanups.pop()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100668 with outcome.testPartExecutor(self):
669 function(*args, **kwargs)
Michael Foordb3468f72010-12-19 03:19:47 +0000670
671 # return this for backwards compatibility
672 # even though we no longer us it internally
673 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000674
675 def __call__(self, *args, **kwds):
676 return self.run(*args, **kwds)
677
678 def debug(self):
679 """Run the test without collecting errors in a TestResult"""
680 self.setUp()
681 getattr(self, self._testMethodName)()
682 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000683 while self._cleanups:
684 function, args, kwargs = self._cleanups.pop(-1)
685 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000686
687 def skipTest(self, reason):
688 """Skip this test."""
689 raise SkipTest(reason)
690
691 def fail(self, msg=None):
692 """Fail immediately, with the given message."""
693 raise self.failureException(msg)
694
695 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000696 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000697 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000698 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699 raise self.failureException(msg)
700
701 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000702 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000703 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000704 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000705 raise self.failureException(msg)
706
707 def _formatMessage(self, msg, standardMsg):
708 """Honour the longMessage attribute when generating failure messages.
709 If longMessage is False this means:
710 * Use only an explicit message if it is provided
711 * Otherwise use the standard message for the assert
712
713 If longMessage is True:
714 * Use the standard message
715 * If an explicit message is provided, plus ' : ' and the explicit message
716 """
717 if not self.longMessage:
718 return msg or standardMsg
719 if msg is None:
720 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000721 try:
722 # don't switch to '{}' formatting in Python 2.X
723 # it changes the way unicode input is handled
724 return '%s : %s' % (standardMsg, msg)
725 except UnicodeDecodeError:
726 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000727
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300728 def assertRaises(self, expected_exception, *args, **kwargs):
729 """Fail unless an exception of class expected_exception is raised
730 by the callable when invoked with specified positional and
731 keyword arguments. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200732 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000733 deemed to have suffered an error, exactly as for an
734 unexpected exception.
735
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300736 If called with the callable and arguments omitted, will return a
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000737 context object used like this::
738
Michael Foord1c42b122010-02-05 22:58:21 +0000739 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000740 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000741
Ezio Melottib4dc2502011-05-06 15:01:41 +0300742 An optional keyword argument 'msg' can be provided when assertRaises
743 is used as a context object.
744
Michael Foord1c42b122010-02-05 22:58:21 +0000745 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000746 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000747 exception after the assertion::
748
749 with self.assertRaises(SomeException) as cm:
750 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000751 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000752 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000753 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300754 context = _AssertRaisesContext(expected_exception, self)
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200755 try:
756 return context.handle('assertRaises', args, kwargs)
757 finally:
758 # bpo-23890: manually break a reference cycle
759 context = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000760
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300761 def assertWarns(self, expected_warning, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000762 """Fail unless a warning of class warnClass is triggered
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300763 by the callable when invoked with specified positional and
764 keyword arguments. If a different type of warning is
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000765 triggered, it will not be handled: depending on the other
766 warning filtering rules in effect, it might be silenced, printed
767 out, or raised as an exception.
768
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300769 If called with the callable and arguments omitted, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000770 context object used like this::
771
772 with self.assertWarns(SomeWarning):
773 do_something()
774
Ezio Melottib4dc2502011-05-06 15:01:41 +0300775 An optional keyword argument 'msg' can be provided when assertWarns
776 is used as a context object.
777
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000778 The context manager keeps a reference to the first matching
779 warning as the 'warning' attribute; similarly, the 'filename'
780 and 'lineno' attributes give you information about the line
781 of Python code from which the warning was triggered.
782 This allows you to inspect the warning after the assertion::
783
784 with self.assertWarns(SomeWarning) as cm:
785 do_something()
786 the_warning = cm.warning
787 self.assertEqual(the_warning.some_attribute, 147)
788 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300789 context = _AssertWarnsContext(expected_warning, self)
790 return context.handle('assertWarns', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000791
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200792 def assertLogs(self, logger=None, level=None):
793 """Fail unless a log message of level *level* or higher is emitted
794 on *logger_name* or its children. If omitted, *level* defaults to
795 INFO and *logger* defaults to the root logger.
796
797 This method must be used as a context manager, and will yield
798 a recording object with two attributes: `output` and `records`.
799 At the end of the context manager, the `output` attribute will
800 be a list of the matching formatted log messages and the
801 `records` attribute will be a list of the corresponding LogRecord
802 objects.
803
804 Example::
805
806 with self.assertLogs('foo', level='INFO') as cm:
807 logging.getLogger('foo').info('first message')
808 logging.getLogger('foo.bar').error('second message')
809 self.assertEqual(cm.output, ['INFO:foo:first message',
810 'ERROR:foo.bar:second message'])
811 """
812 return _AssertLogsContext(self, logger, level)
813
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000814 def _getAssertEqualityFunc(self, first, second):
815 """Get a detailed comparison function for the types of the two args.
816
817 Returns: A callable accepting (first, second, msg=None) that will
818 raise a failure exception if first != second with a useful human
819 readable error message for those types.
820 """
821 #
822 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
823 # and vice versa. I opted for the conservative approach in case
824 # subclasses are not intended to be compared in detail to their super
825 # class instances using a type equality func. This means testing
826 # subtypes won't automagically use the detailed comparison. Callers
827 # should use their type specific assertSpamEqual method to compare
828 # subclasses if the detailed comparison is desired and appropriate.
829 # See the discussion in http://bugs.python.org/issue2578.
830 #
831 if type(first) is type(second):
832 asserter = self._type_equality_funcs.get(type(first))
833 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500834 if isinstance(asserter, str):
835 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000836 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000837
838 return self._baseAssertEqual
839
840 def _baseAssertEqual(self, first, second, msg=None):
841 """The default assertEqual implementation, not type specific."""
842 if not first == second:
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300843 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000844 msg = self._formatMessage(msg, standardMsg)
845 raise self.failureException(msg)
846
847 def assertEqual(self, first, second, msg=None):
848 """Fail if the two objects are unequal as determined by the '=='
849 operator.
850 """
851 assertion_func = self._getAssertEqualityFunc(first, second)
852 assertion_func(first, second, msg=msg)
853
854 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200855 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000856 operator.
857 """
858 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000859 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
860 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000861 raise self.failureException(msg)
862
Michael Foord321d0592010-11-02 13:44:51 +0000863 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000864 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000865 """Fail if the two objects are unequal as determined by their
866 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000867 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300868 difference between the two objects is more than the given
869 delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000870
871 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000872 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000873
874 If the two objects compare equal then they will automatically
875 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000876 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000877 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000878 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000879 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000880 if delta is not None and places is not None:
881 raise TypeError("specify delta or places not both")
882
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200883 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000884 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200885 if diff <= delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000886 return
887
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200888 standardMsg = '%s != %s within %s delta (%s difference)' % (
889 safe_repr(first),
890 safe_repr(second),
891 safe_repr(delta),
892 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000893 else:
894 if places is None:
895 places = 7
896
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200897 if round(diff, places) == 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000898 return
899
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200900 standardMsg = '%s != %s within %r places (%s difference)' % (
901 safe_repr(first),
902 safe_repr(second),
903 places,
904 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000905 msg = self._formatMessage(msg, standardMsg)
906 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000907
Michael Foord321d0592010-11-02 13:44:51 +0000908 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000909 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000910 """Fail if the two objects are equal as determined by their
911 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000912 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300913 difference between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000914
915 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000916 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000917
918 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000919 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000920 if delta is not None and places is not None:
921 raise TypeError("specify delta or places not both")
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200922 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000923 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200924 if not (first == second) and diff > delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000925 return
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200926 standardMsg = '%s == %s within %s delta (%s difference)' % (
927 safe_repr(first),
928 safe_repr(second),
929 safe_repr(delta),
930 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000931 else:
932 if places is None:
933 places = 7
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200934 if not (first == second) and round(diff, places) != 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000935 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000936 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000937 safe_repr(second),
938 places)
939
940 msg = self._formatMessage(msg, standardMsg)
941 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000942
Michael Foord085dfd32010-06-05 12:17:02 +0000943 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000944 """An equality assertion for ordered sequences (like lists and tuples).
945
R. David Murrayad13f222010-01-29 22:17:58 +0000946 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000947 which can be indexed, has a length, and has an equality operator.
948
949 Args:
950 seq1: The first sequence to compare.
951 seq2: The second sequence to compare.
952 seq_type: The expected datatype of the sequences, or None if no
953 datatype should be enforced.
954 msg: Optional message to use on failure instead of a list of
955 differences.
956 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400957 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000958 seq_type_name = seq_type.__name__
959 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000960 raise self.failureException('First sequence is not a %s: %s'
961 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000962 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000963 raise self.failureException('Second sequence is not a %s: %s'
964 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000965 else:
966 seq_type_name = "sequence"
967
968 differing = None
969 try:
970 len1 = len(seq1)
971 except (TypeError, NotImplementedError):
972 differing = 'First %s has no length. Non-sequence?' % (
973 seq_type_name)
974
975 if differing is None:
976 try:
977 len2 = len(seq2)
978 except (TypeError, NotImplementedError):
979 differing = 'Second %s has no length. Non-sequence?' % (
980 seq_type_name)
981
982 if differing is None:
983 if seq1 == seq2:
984 return
985
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300986 differing = '%ss differ: %s != %s\n' % (
987 (seq_type_name.capitalize(),) +
988 _common_shorten_repr(seq1, seq2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000989
990 for i in range(min(len1, len2)):
991 try:
992 item1 = seq1[i]
993 except (TypeError, IndexError, NotImplementedError):
994 differing += ('\nUnable to index element %d of first %s\n' %
995 (i, seq_type_name))
996 break
997
998 try:
999 item2 = seq2[i]
1000 except (TypeError, IndexError, NotImplementedError):
1001 differing += ('\nUnable to index element %d of second %s\n' %
1002 (i, seq_type_name))
1003 break
1004
1005 if item1 != item2:
1006 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001007 ((i,) + _common_shorten_repr(item1, item2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001008 break
1009 else:
1010 if (len1 == len2 and seq_type is None and
1011 type(seq1) != type(seq2)):
1012 # The sequences are the same, but have differing types.
1013 return
1014
1015 if len1 > len2:
1016 differing += ('\nFirst %s contains %d additional '
1017 'elements.\n' % (seq_type_name, len1 - len2))
1018 try:
1019 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001020 (len2, safe_repr(seq1[len2])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001021 except (TypeError, IndexError, NotImplementedError):
1022 differing += ('Unable to index element %d '
1023 'of first %s\n' % (len2, seq_type_name))
1024 elif len1 < len2:
1025 differing += ('\nSecond %s contains %d additional '
1026 'elements.\n' % (seq_type_name, len2 - len1))
1027 try:
1028 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001029 (len1, safe_repr(seq2[len1])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001030 except (TypeError, IndexError, NotImplementedError):
1031 differing += ('Unable to index element %d '
1032 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +00001033 standardMsg = differing
1034 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001035 difflib.ndiff(pprint.pformat(seq1).splitlines(),
1036 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +00001037
1038 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001039 msg = self._formatMessage(msg, standardMsg)
1040 self.fail(msg)
1041
Michael Foord085dfd32010-06-05 12:17:02 +00001042 def _truncateMessage(self, message, diff):
1043 max_diff = self.maxDiff
1044 if max_diff is None or len(diff) <= max_diff:
1045 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +00001046 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +00001047
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001048 def assertListEqual(self, list1, list2, msg=None):
1049 """A list-specific equality assertion.
1050
1051 Args:
1052 list1: The first list to compare.
1053 list2: The second list to compare.
1054 msg: Optional message to use on failure instead of a list of
1055 differences.
1056
1057 """
1058 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
1059
1060 def assertTupleEqual(self, tuple1, tuple2, msg=None):
1061 """A tuple-specific equality assertion.
1062
1063 Args:
1064 tuple1: The first tuple to compare.
1065 tuple2: The second tuple to compare.
1066 msg: Optional message to use on failure instead of a list of
1067 differences.
1068 """
1069 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1070
1071 def assertSetEqual(self, set1, set2, msg=None):
1072 """A set-specific equality assertion.
1073
1074 Args:
1075 set1: The first set to compare.
1076 set2: The second set to compare.
1077 msg: Optional message to use on failure instead of a list of
1078 differences.
1079
Michael Foord91c9da32010-03-20 17:21:27 +00001080 assertSetEqual uses ducktyping to support different types of sets, and
1081 is optimized for sets specifically (parameters must support a
1082 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001083 """
1084 try:
1085 difference1 = set1.difference(set2)
1086 except TypeError as e:
1087 self.fail('invalid type when attempting set difference: %s' % e)
1088 except AttributeError as e:
1089 self.fail('first argument does not support set difference: %s' % e)
1090
1091 try:
1092 difference2 = set2.difference(set1)
1093 except TypeError as e:
1094 self.fail('invalid type when attempting set difference: %s' % e)
1095 except AttributeError as e:
1096 self.fail('second argument does not support set difference: %s' % e)
1097
1098 if not (difference1 or difference2):
1099 return
1100
1101 lines = []
1102 if difference1:
1103 lines.append('Items in the first set but not the second:')
1104 for item in difference1:
1105 lines.append(repr(item))
1106 if difference2:
1107 lines.append('Items in the second set but not the first:')
1108 for item in difference2:
1109 lines.append(repr(item))
1110
1111 standardMsg = '\n'.join(lines)
1112 self.fail(self._formatMessage(msg, standardMsg))
1113
1114 def assertIn(self, member, container, msg=None):
1115 """Just like self.assertTrue(a in b), but with a nicer default message."""
1116 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001117 standardMsg = '%s not found in %s' % (safe_repr(member),
1118 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001119 self.fail(self._formatMessage(msg, standardMsg))
1120
1121 def assertNotIn(self, member, container, msg=None):
1122 """Just like self.assertTrue(a not in b), but with a nicer default message."""
1123 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001124 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1125 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001126 self.fail(self._formatMessage(msg, standardMsg))
1127
1128 def assertIs(self, expr1, expr2, msg=None):
1129 """Just like self.assertTrue(a is b), but with a nicer default message."""
1130 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001131 standardMsg = '%s is not %s' % (safe_repr(expr1),
1132 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001133 self.fail(self._formatMessage(msg, standardMsg))
1134
1135 def assertIsNot(self, expr1, expr2, msg=None):
1136 """Just like self.assertTrue(a is not b), but with a nicer default message."""
1137 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001138 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001139 self.fail(self._formatMessage(msg, standardMsg))
1140
1141 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001142 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1143 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001144
1145 if d1 != d2:
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001146 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
Michael Foord085dfd32010-06-05 12:17:02 +00001147 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001148 pprint.pformat(d1).splitlines(),
1149 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +00001150 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001151 self.fail(self._formatMessage(msg, standardMsg))
1152
Ezio Melotti0f535012011-04-03 18:02:13 +03001153 def assertDictContainsSubset(self, subset, dictionary, msg=None):
1154 """Checks whether dictionary is a superset of subset."""
1155 warnings.warn('assertDictContainsSubset is deprecated',
1156 DeprecationWarning)
1157 missing = []
1158 mismatched = []
1159 for key, value in subset.items():
1160 if key not in dictionary:
1161 missing.append(key)
1162 elif value != dictionary[key]:
1163 mismatched.append('%s, expected: %s, actual: %s' %
1164 (safe_repr(key), safe_repr(value),
1165 safe_repr(dictionary[key])))
1166
1167 if not (missing or mismatched):
1168 return
1169
1170 standardMsg = ''
1171 if missing:
1172 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1173 missing)
1174 if mismatched:
1175 if standardMsg:
1176 standardMsg += '; '
1177 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1178
1179 self.fail(self._formatMessage(msg, standardMsg))
1180
1181
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001182 def assertCountEqual(self, first, second, msg=None):
1183 """An unordered sequence comparison asserting that the same elements,
1184 regardless of order. If the same element occurs more than once,
1185 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001186
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001187 self.assertEqual(Counter(list(first)),
1188 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001189
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001190 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001191 - [0, 1, 1] and [1, 0, 1] compare equal.
1192 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001193
Michael Foord8442a602010-03-20 16:58:04 +00001194 """
Michael Foorde180d392011-01-28 19:51:48 +00001195 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001196 try:
Michael Foorde180d392011-01-28 19:51:48 +00001197 first = collections.Counter(first_seq)
1198 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001199 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001200 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001201 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001202 else:
Michael Foorde180d392011-01-28 19:51:48 +00001203 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001204 return
Michael Foorde180d392011-01-28 19:51:48 +00001205 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001206
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001207 if differences:
1208 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001209 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001210 diffMsg = '\n'.join(lines)
1211 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1212 msg = self._formatMessage(msg, standardMsg)
1213 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001214
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001215 def assertMultiLineEqual(self, first, second, msg=None):
1216 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001217 self.assertIsInstance(first, str, 'First argument is not a string')
1218 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001219
1220 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001221 # don't use difflib if the strings are too long
1222 if (len(first) > self._diffThreshold or
1223 len(second) > self._diffThreshold):
1224 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001225 firstlines = first.splitlines(keepends=True)
1226 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001227 if len(firstlines) == 1 and first.strip('\r\n') == first:
1228 firstlines = [first + '\n']
1229 secondlines = [second + '\n']
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001230 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Michael Foordc653ce32010-07-10 13:52:22 +00001231 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001232 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001233 self.fail(self._formatMessage(msg, standardMsg))
1234
1235 def assertLess(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 less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001239 self.fail(self._formatMessage(msg, standardMsg))
1240
1241 def assertLessEqual(self, a, b, msg=None):
1242 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1243 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001244 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001245 self.fail(self._formatMessage(msg, standardMsg))
1246
1247 def assertGreater(self, a, b, msg=None):
1248 """Just like self.assertTrue(a > b), but with a nicer default message."""
1249 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001250 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001251 self.fail(self._formatMessage(msg, standardMsg))
1252
1253 def assertGreaterEqual(self, a, b, msg=None):
1254 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1255 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001256 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001257 self.fail(self._formatMessage(msg, standardMsg))
1258
1259 def assertIsNone(self, obj, msg=None):
1260 """Same as self.assertTrue(obj is None), with a nicer default message."""
1261 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001262 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001263 self.fail(self._formatMessage(msg, standardMsg))
1264
1265 def assertIsNotNone(self, obj, msg=None):
1266 """Included for symmetry with assertIsNone."""
1267 if obj is None:
1268 standardMsg = 'unexpectedly None'
1269 self.fail(self._formatMessage(msg, standardMsg))
1270
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001271 def assertIsInstance(self, obj, cls, msg=None):
1272 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1273 default message."""
1274 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001275 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001276 self.fail(self._formatMessage(msg, standardMsg))
1277
1278 def assertNotIsInstance(self, obj, cls, msg=None):
1279 """Included for symmetry with assertIsInstance."""
1280 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001281 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001282 self.fail(self._formatMessage(msg, standardMsg))
1283
Ezio Melottied3a7d22010-12-01 02:32:32 +00001284 def assertRaisesRegex(self, expected_exception, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001285 *args, **kwargs):
Ezio Melottied3a7d22010-12-01 02:32:32 +00001286 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001287
1288 Args:
1289 expected_exception: Exception class expected to be raised.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001290 expected_regex: Regex (re.Pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001291 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001292 args: Function to be called and extra positional args.
1293 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001294 msg: Optional message used in case of failure. Can only be used
1295 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001296 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001297 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1298 return context.handle('assertRaisesRegex', args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001299
Ezio Melottied3a7d22010-12-01 02:32:32 +00001300 def assertWarnsRegex(self, expected_warning, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001301 *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001302 """Asserts that the message in a triggered warning matches a regexp.
1303 Basic functioning is similar to assertWarns() with the addition
1304 that only warnings whose messages also match the regular expression
1305 are considered successful matches.
1306
1307 Args:
1308 expected_warning: Warning class expected to be triggered.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001309 expected_regex: Regex (re.Pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001310 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001311 args: Function to be called and extra positional args.
1312 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001313 msg: Optional message used in case of failure. Can only be used
1314 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001315 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001316 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1317 return context.handle('assertWarnsRegex', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001318
Ezio Melottied3a7d22010-12-01 02:32:32 +00001319 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001320 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001321 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001322 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001323 expected_regex = re.compile(expected_regex)
1324 if not expected_regex.search(text):
Robert Collinsbe6caca2015-08-20 11:13:09 +12001325 standardMsg = "Regex didn't match: %r not found in %r" % (
1326 expected_regex.pattern, text)
1327 # _formatMessage ensures the longMessage option is respected
1328 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001329 raise self.failureException(msg)
1330
Ezio Melotti8f776302010-12-10 02:32:05 +00001331 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001332 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001333 if isinstance(unexpected_regex, (str, bytes)):
1334 unexpected_regex = re.compile(unexpected_regex)
1335 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001336 if match:
Robert Collinsbe6caca2015-08-20 11:13:09 +12001337 standardMsg = 'Regex matched: %r matches %r in %r' % (
1338 text[match.start() : match.end()],
1339 unexpected_regex.pattern,
1340 text)
1341 # _formatMessage ensures the longMessage option is respected
1342 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001343 raise self.failureException(msg)
1344
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001345
Ezio Melottied3a7d22010-12-01 02:32:32 +00001346 def _deprecate(original_func):
1347 def deprecated_func(*args, **kwargs):
1348 warnings.warn(
1349 'Please use {0} instead.'.format(original_func.__name__),
1350 DeprecationWarning, 2)
1351 return original_func(*args, **kwargs)
1352 return deprecated_func
1353
Ezio Melotti361467e2011-04-03 17:37:58 +03001354 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001355 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1356 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1357 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1358 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1359 failUnless = assert_ = _deprecate(assertTrue)
1360 failUnlessRaises = _deprecate(assertRaises)
1361 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001362 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1363 assertRegexpMatches = _deprecate(assertRegex)
Robert Collinsbe6caca2015-08-20 11:13:09 +12001364 assertNotRegexpMatches = _deprecate(assertNotRegex)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001365
1366
1367
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001368class FunctionTestCase(TestCase):
1369 """A test case that wraps a test function.
1370
1371 This is useful for slipping pre-existing test functions into the
1372 unittest framework. Optionally, set-up and tidy-up functions can be
1373 supplied. As with TestCase, the tidy-up ('tearDown') function will
1374 always be called if the set-up ('setUp') function ran successfully.
1375 """
1376
1377 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1378 super(FunctionTestCase, self).__init__()
1379 self._setUpFunc = setUp
1380 self._tearDownFunc = tearDown
1381 self._testFunc = testFunc
1382 self._description = description
1383
1384 def setUp(self):
1385 if self._setUpFunc is not None:
1386 self._setUpFunc()
1387
1388 def tearDown(self):
1389 if self._tearDownFunc is not None:
1390 self._tearDownFunc()
1391
1392 def runTest(self):
1393 self._testFunc()
1394
1395 def id(self):
1396 return self._testFunc.__name__
1397
1398 def __eq__(self, other):
1399 if not isinstance(other, self.__class__):
1400 return NotImplemented
1401
1402 return self._setUpFunc == other._setUpFunc and \
1403 self._tearDownFunc == other._tearDownFunc and \
1404 self._testFunc == other._testFunc and \
1405 self._description == other._description
1406
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001407 def __hash__(self):
1408 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1409 self._testFunc, self._description))
1410
1411 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001412 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001413 self._testFunc.__name__)
1414
1415 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001416 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001417 self._testFunc)
1418
1419 def shortDescription(self):
1420 if self._description is not None:
1421 return self._description
1422 doc = self._testFunc.__doc__
1423 return doc and doc.split("\n")[0].strip() or None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001424
1425
1426class _SubTest(TestCase):
1427
1428 def __init__(self, test_case, message, params):
1429 super().__init__()
1430 self._message = message
1431 self.test_case = test_case
1432 self.params = params
1433 self.failureException = test_case.failureException
1434
1435 def runTest(self):
1436 raise NotImplementedError("subtests cannot be run directly")
1437
1438 def _subDescription(self):
1439 parts = []
Berker Peksag16ea19f2016-09-21 19:34:15 +03001440 if self._message is not _subtest_msg_sentinel:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001441 parts.append("[{}]".format(self._message))
1442 if self.params:
1443 params_desc = ', '.join(
1444 "{}={!r}".format(k, v)
Serhiy Storchaka48fbe522017-06-23 21:47:39 +03001445 for (k, v) in self.params.items())
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001446 parts.append("({})".format(params_desc))
1447 return " ".join(parts) or '(<subtest>)'
1448
1449 def id(self):
1450 return "{} {}".format(self.test_case.id(), self._subDescription())
1451
1452 def shortDescription(self):
1453 """Returns a one-line description of the subtest, or None if no
1454 description has been provided.
1455 """
1456 return self.test_case.shortDescription()
1457
1458 def __str__(self):
1459 return "{} {}".format(self.test_case, self._subDescription())