blob: 8e01c3dc7bbd12ddff7f247853e3c993997fe604 [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
Lisa Roach0f221d02018-11-08 18:34:33 -080087
88_module_cleanups = []
Serhiy Storchaka42a139e2019-04-01 09:16:35 +030089def addModuleCleanup(*args, **kwargs):
Lisa Roach0f221d02018-11-08 18:34:33 -080090 """Same as addCleanup, except the cleanup items are called even if
91 setUpModule fails (unlike tearDownModule)."""
Serhiy Storchaka42a139e2019-04-01 09:16:35 +030092 if args:
93 function, *args = args
94 elif 'function' in kwargs:
95 function = kwargs.pop('function')
96 import warnings
97 warnings.warn("Passing 'function' as keyword argument is deprecated",
98 DeprecationWarning, stacklevel=2)
99 else:
100 raise TypeError('addModuleCleanup expected at least 1 positional '
101 'argument, got %d' % (len(args)-1))
102 args = tuple(args)
103
Lisa Roach0f221d02018-11-08 18:34:33 -0800104 _module_cleanups.append((function, args, kwargs))
Serhiy Storchakad53cf992019-05-06 22:40:27 +0300105addModuleCleanup.__text_signature__ = '(function, /, *args, **kwargs)'
Lisa Roach0f221d02018-11-08 18:34:33 -0800106
107
108def doModuleCleanups():
109 """Execute all module cleanup functions. Normally called for you after
110 tearDownModule."""
111 exceptions = []
112 while _module_cleanups:
113 function, args, kwargs = _module_cleanups.pop()
114 try:
115 function(*args, **kwargs)
116 except Exception as exc:
117 exceptions.append(exc)
118 if exceptions:
119 # Swallows all but first exception. If a multi-exception handler
120 # gets written we should use that here instead.
121 raise exceptions[0]
122
123
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000124def skip(reason):
125 """
126 Unconditionally skip a test.
127 """
128 def decorator(test_item):
Antoine Pitroub05ac862012-04-25 14:56:46 +0200129 if not isinstance(test_item, type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000130 @functools.wraps(test_item)
131 def skip_wrapper(*args, **kwargs):
132 raise SkipTest(reason)
133 test_item = skip_wrapper
134
135 test_item.__unittest_skip__ = True
136 test_item.__unittest_skip_why__ = reason
137 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138 return decorator
139
140def skipIf(condition, reason):
141 """
142 Skip a test if the condition is true.
143 """
144 if condition:
145 return skip(reason)
146 return _id
147
148def skipUnless(condition, reason):
149 """
150 Skip a test unless the condition is true.
151 """
152 if not condition:
153 return skip(reason)
154 return _id
155
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100156def expectedFailure(test_item):
157 test_item.__unittest_expecting_failure__ = True
158 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000159
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300160def _is_subtype(expected, basetype):
161 if isinstance(expected, tuple):
162 return all(_is_subtype(e, basetype) for e in expected)
163 return isinstance(expected, type) and issubclass(expected, basetype)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000164
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200165class _BaseTestCaseContext:
166
167 def __init__(self, test_case):
168 self.test_case = test_case
169
170 def _raiseFailure(self, standardMsg):
171 msg = self.test_case._formatMessage(self.msg, standardMsg)
172 raise self.test_case.failureException(msg)
173
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200174class _AssertRaisesBaseContext(_BaseTestCaseContext):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000175
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300176 def __init__(self, expected, test_case, expected_regex=None):
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200177 _BaseTestCaseContext.__init__(self, test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000178 self.expected = expected
Ezio Melottib4dc2502011-05-06 15:01:41 +0300179 self.test_case = test_case
R David Murrayef1c2672014-03-25 15:31:50 -0400180 if expected_regex is not None:
Ezio Melottied3a7d22010-12-01 02:32:32 +0000181 expected_regex = re.compile(expected_regex)
182 self.expected_regex = expected_regex
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300183 self.obj_name = None
Ezio Melottib4dc2502011-05-06 15:01:41 +0300184 self.msg = None
185
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300186 def handle(self, name, args, kwargs):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300187 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300188 If args is empty, assertRaises/Warns is being used as a
Ezio Melottib4dc2502011-05-06 15:01:41 +0300189 context manager, so check for a 'msg' kwarg and return self.
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300190 If args is not empty, call a callable passing positional and keyword
191 arguments.
Ezio Melottib4dc2502011-05-06 15:01:41 +0300192 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300193 try:
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200194 if not _is_subtype(self.expected, self._base_type):
195 raise TypeError('%s() arg 1 must be %s' %
196 (name, self._base_type_str))
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200197 if not args:
198 self.msg = kwargs.pop('msg', None)
199 if kwargs:
Serhiy Storchaka77d57812018-08-19 10:00:11 +0300200 raise TypeError('%r is an invalid keyword argument for '
201 'this function' % (next(iter(kwargs)),))
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200202 return self
203
204 callable_obj, *args = args
205 try:
206 self.obj_name = callable_obj.__name__
207 except AttributeError:
208 self.obj_name = str(callable_obj)
209 with self:
210 callable_obj(*args, **kwargs)
211 finally:
212 # bpo-23890: manually break a reference cycle
213 self = None
Ezio Melottib4dc2502011-05-06 15:01:41 +0300214
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000215
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000216class _AssertRaisesContext(_AssertRaisesBaseContext):
217 """A context manager used to implement TestCase.assertRaises* methods."""
218
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300219 _base_type = BaseException
220 _base_type_str = 'an exception type or tuple of exception types'
221
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000222 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000223 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000224
225 def __exit__(self, exc_type, exc_value, tb):
226 if exc_type is None:
227 try:
228 exc_name = self.expected.__name__
229 except AttributeError:
230 exc_name = str(self.expected)
231 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300232 self._raiseFailure("{} not raised by {}".format(exc_name,
233 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000234 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300235 self._raiseFailure("{} not raised".format(exc_name))
Antoine Pitrou96810222014-04-29 01:23:50 +0200236 else:
237 traceback.clear_frames(tb)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000238 if not issubclass(exc_type, self.expected):
239 # let unexpected exceptions pass through
240 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000241 # store exception, without traceback, for later retrieval
242 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000243 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000244 return True
245
Ezio Melottied3a7d22010-12-01 02:32:32 +0000246 expected_regex = self.expected_regex
247 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300248 self._raiseFailure('"{}" does not match "{}"'.format(
249 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000250 return True
251
252
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000253class _AssertWarnsContext(_AssertRaisesBaseContext):
254 """A context manager used to implement TestCase.assertWarns* methods."""
255
Serhiy Storchaka041dd8e2015-05-21 20:15:40 +0300256 _base_type = Warning
257 _base_type_str = 'a warning type or tuple of warning types'
258
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000259 def __enter__(self):
260 # The __warningregistry__'s need to be in a pristine state for tests
261 # to work properly.
262 for v in sys.modules.values():
263 if getattr(v, '__warningregistry__', None):
264 v.__warningregistry__ = {}
265 self.warnings_manager = warnings.catch_warnings(record=True)
266 self.warnings = self.warnings_manager.__enter__()
267 warnings.simplefilter("always", self.expected)
268 return self
269
270 def __exit__(self, exc_type, exc_value, tb):
271 self.warnings_manager.__exit__(exc_type, exc_value, tb)
272 if exc_type is not None:
273 # let unexpected exceptions pass through
274 return
275 try:
276 exc_name = self.expected.__name__
277 except AttributeError:
278 exc_name = str(self.expected)
279 first_matching = None
280 for m in self.warnings:
281 w = m.message
282 if not isinstance(w, self.expected):
283 continue
284 if first_matching is None:
285 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000286 if (self.expected_regex is not None and
287 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000288 continue
289 # store warning for later retrieval
290 self.warning = w
291 self.filename = m.filename
292 self.lineno = m.lineno
293 return
294 # Now we simply try to choose a helpful failure message
295 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300296 self._raiseFailure('"{}" does not match "{}"'.format(
297 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000298 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300299 self._raiseFailure("{} not triggered by {}".format(exc_name,
300 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000301 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300302 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000303
304
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200305
306_LoggingWatcher = collections.namedtuple("_LoggingWatcher",
307 ["records", "output"])
308
309
310class _CapturingHandler(logging.Handler):
311 """
312 A logging handler capturing all (raw and formatted) logging output.
313 """
314
315 def __init__(self):
316 logging.Handler.__init__(self)
317 self.watcher = _LoggingWatcher([], [])
318
319 def flush(self):
320 pass
321
322 def emit(self, record):
323 self.watcher.records.append(record)
324 msg = self.format(record)
325 self.watcher.output.append(msg)
326
327
328
329class _AssertLogsContext(_BaseTestCaseContext):
330 """A context manager used to implement TestCase.assertLogs()."""
331
332 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
333
334 def __init__(self, test_case, logger_name, level):
335 _BaseTestCaseContext.__init__(self, test_case)
336 self.logger_name = logger_name
337 if level:
338 self.level = logging._nameToLevel.get(level, level)
339 else:
340 self.level = logging.INFO
341 self.msg = None
342
343 def __enter__(self):
344 if isinstance(self.logger_name, logging.Logger):
345 logger = self.logger = self.logger_name
346 else:
347 logger = self.logger = logging.getLogger(self.logger_name)
348 formatter = logging.Formatter(self.LOGGING_FORMAT)
349 handler = _CapturingHandler()
350 handler.setFormatter(formatter)
351 self.watcher = handler.watcher
352 self.old_handlers = logger.handlers[:]
353 self.old_level = logger.level
354 self.old_propagate = logger.propagate
355 logger.handlers = [handler]
356 logger.setLevel(self.level)
357 logger.propagate = False
358 return handler.watcher
359
360 def __exit__(self, exc_type, exc_value, tb):
361 self.logger.handlers = self.old_handlers
362 self.logger.propagate = self.old_propagate
363 self.logger.setLevel(self.old_level)
364 if exc_type is not None:
365 # let unexpected exceptions pass through
366 return False
367 if len(self.watcher.records) == 0:
368 self._raiseFailure(
369 "no logs of level {} or higher triggered on {}"
370 .format(logging.getLevelName(self.level), self.logger.name))
371
372
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300373class _OrderedChainMap(collections.ChainMap):
374 def __iter__(self):
375 seen = set()
376 for mapping in self.maps:
377 for k in mapping:
378 if k not in seen:
379 seen.add(k)
380 yield k
381
382
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000383class TestCase(object):
384 """A class whose instances are single test cases.
385
386 By default, the test code itself should be placed in a method named
387 'runTest'.
388
389 If the fixture may be used for many test cases, create as
390 many test methods as are needed. When instantiating such a TestCase
391 subclass, specify in the constructor arguments the name of the test method
392 that the instance is to execute.
393
394 Test authors should subclass TestCase for their own tests. Construction
395 and deconstruction of the test's environment ('fixture') can be
396 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
397
398 If it is necessary to override the __init__ method, the base class
399 __init__ method must always be called. It is important that subclasses
400 should not change the signature of their __init__ method, since instances
401 of the classes are instantiated automatically by parts of the framework
402 in order to be run.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000403
Ezio Melotti31797e52013-03-29 03:42:29 +0200404 When subclassing TestCase, you can set these attributes:
405 * failureException: determines which exception will be raised when
406 the instance's assertion methods fail; test methods raising this
407 exception will be deemed to have 'failed' rather than 'errored'.
408 * longMessage: determines whether long messages (including repr of
409 objects used in assert methods) will be printed on failure in *addition*
410 to any explicit message passed.
411 * maxDiff: sets the maximum length of a diff in failure messages
412 by assert methods using difflib. It is looked up as an instance
413 attribute so can be configured by individual tests if required.
414 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000415
416 failureException = AssertionError
417
Michael Foord5074df62010-12-03 00:53:09 +0000418 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000419
Michael Foord085dfd32010-06-05 12:17:02 +0000420 maxDiff = 80*8
421
Ezio Melottiedd117f2011-04-27 10:20:38 +0300422 # If a string is longer than _diffThreshold, use normal comparison instead
423 # of difflib. See #11763.
424 _diffThreshold = 2**16
425
Benjamin Peterson847a4112010-03-14 15:04:17 +0000426 # Attribute used by TestSuite for classSetUp
427
428 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000429
Lisa Roach0f221d02018-11-08 18:34:33 -0800430 _class_cleanups = []
431
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000432 def __init__(self, methodName='runTest'):
433 """Create an instance of the class that will use the named test
434 method when executed. Raises a ValueError if the instance does
435 not have a method with the specified name.
436 """
437 self._testMethodName = methodName
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100438 self._outcome = None
Michael Foord32e1d832011-01-03 17:00:11 +0000439 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000440 try:
441 testMethod = getattr(self, methodName)
442 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000443 if methodName != 'runTest':
444 # we allow instantiation with no explicit method name
445 # but not an *incorrect* or missing method name
446 raise ValueError("no such test method in %s: %s" %
447 (self.__class__, methodName))
448 else:
449 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000450 self._cleanups = []
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100451 self._subtest = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000452
453 # Map types to custom assertEqual functions that will compare
454 # instances of said type in more detail to generate a more useful
455 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500456 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000457 self.addTypeEqualityFunc(dict, 'assertDictEqual')
458 self.addTypeEqualityFunc(list, 'assertListEqual')
459 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
460 self.addTypeEqualityFunc(set, 'assertSetEqual')
461 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
462 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000463
464 def addTypeEqualityFunc(self, typeobj, function):
465 """Add a type specific assertEqual style function to compare a type.
466
467 This method is for use by TestCase subclasses that need to register
468 their own type equality functions to provide nicer error messages.
469
470 Args:
471 typeobj: The data type to call this function on when both values
472 are of the same type in assertEqual().
473 function: The callable taking two arguments and an optional
474 msg= argument that raises self.failureException with a
475 useful error message when the two arguments are not equal.
476 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000477 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000478
Serhiy Storchaka42a139e2019-04-01 09:16:35 +0300479 def addCleanup(*args, **kwargs):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000480 """Add a function, with arguments, to be called when the test is
481 completed. Functions added are called on a LIFO basis and are
482 called after tearDown on test failure or success.
483
484 Cleanup items are called even if setUp fails (unlike tearDown)."""
Serhiy Storchaka42a139e2019-04-01 09:16:35 +0300485 if len(args) >= 2:
486 self, function, *args = args
487 elif not args:
488 raise TypeError("descriptor 'addCleanup' of 'TestCase' object "
489 "needs an argument")
490 elif 'function' in kwargs:
491 function = kwargs.pop('function')
492 self, *args = args
493 import warnings
494 warnings.warn("Passing 'function' as keyword argument is deprecated",
495 DeprecationWarning, stacklevel=2)
496 else:
497 raise TypeError('addCleanup expected at least 1 positional '
498 'argument, got %d' % (len(args)-1))
499 args = tuple(args)
500
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000501 self._cleanups.append((function, args, kwargs))
Serhiy Storchakad53cf992019-05-06 22:40:27 +0300502 addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000503
Serhiy Storchaka42a139e2019-04-01 09:16:35 +0300504 def addClassCleanup(*args, **kwargs):
Lisa Roach0f221d02018-11-08 18:34:33 -0800505 """Same as addCleanup, except the cleanup items are called even if
506 setUpClass fails (unlike tearDownClass)."""
Serhiy Storchaka42a139e2019-04-01 09:16:35 +0300507 if len(args) >= 2:
508 cls, function, *args = args
509 elif not args:
510 raise TypeError("descriptor 'addClassCleanup' of 'TestCase' object "
511 "needs an argument")
512 else:
513 raise TypeError('addClassCleanup expected at least 1 positional '
514 'argument, got %d' % (len(args)-1))
515 args = tuple(args)
516
Lisa Roach0f221d02018-11-08 18:34:33 -0800517 cls._class_cleanups.append((function, args, kwargs))
Serhiy Storchakad53cf992019-05-06 22:40:27 +0300518 addClassCleanup.__text_signature__ = '($cls, function, /, *args, **kwargs)'
519 addClassCleanup = classmethod(addClassCleanup)
Lisa Roach0f221d02018-11-08 18:34:33 -0800520
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000521 def setUp(self):
522 "Hook method for setting up the test fixture before exercising it."
523 pass
524
525 def tearDown(self):
526 "Hook method for deconstructing the test fixture after testing it."
527 pass
528
Benjamin Peterson847a4112010-03-14 15:04:17 +0000529 @classmethod
530 def setUpClass(cls):
531 "Hook method for setting up class fixture before running tests in the class."
532
533 @classmethod
534 def tearDownClass(cls):
535 "Hook method for deconstructing the class fixture after running all tests in the class."
536
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000537 def countTestCases(self):
538 return 1
539
540 def defaultTestResult(self):
541 return result.TestResult()
542
543 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000544 """Returns a one-line description of the test, or None if no
545 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000546
Michael Foord34c94622010-02-10 15:51:42 +0000547 The default implementation of this method returns the first line of
548 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000549 """
Michael Foord34c94622010-02-10 15:51:42 +0000550 doc = self._testMethodDoc
551 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000552
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000553
554 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000555 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000556
557 def __eq__(self, other):
558 if type(self) is not type(other):
559 return NotImplemented
560
561 return self._testMethodName == other._testMethodName
562
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000563 def __hash__(self):
564 return hash((type(self), self._testMethodName))
565
566 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000567 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000568
569 def __repr__(self):
570 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000571 (strclass(self.__class__), self._testMethodName)
572
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100573 def _addSkip(self, result, test_case, reason):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000574 addSkip = getattr(result, 'addSkip', None)
575 if addSkip is not None:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100576 addSkip(test_case, reason)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000577 else:
578 warnings.warn("TestResult has no addSkip method, skips not reported",
579 RuntimeWarning, 2)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100580 result.addSuccess(test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000581
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100582 @contextlib.contextmanager
Berker Peksag16ea19f2016-09-21 19:34:15 +0300583 def subTest(self, msg=_subtest_msg_sentinel, **params):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100584 """Return a context manager that will return the enclosed block
585 of code in a subtest identified by the optional message and
586 keyword parameters. A failure in the subtest marks the test
587 case as failed but resumes execution at the end of the enclosed
588 block, allowing further test code to be executed.
589 """
Bruno Oliveirada2bf9f2018-10-12 07:35:55 -0300590 if self._outcome is None or not self._outcome.result_supports_subtests:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100591 yield
592 return
593 parent = self._subtest
594 if parent is None:
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300595 params_map = _OrderedChainMap(params)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100596 else:
597 params_map = parent.params.new_child(params)
598 self._subtest = _SubTest(self, msg, params_map)
Michael Foordb3468f72010-12-19 03:19:47 +0000599 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100600 with self._outcome.testPartExecutor(self._subtest, isTest=True):
601 yield
602 if not self._outcome.success:
603 result = self._outcome.result
604 if result is not None and result.failfast:
605 raise _ShouldStop
606 elif self._outcome.expectedFailure:
607 # If the test is expecting a failure, we really want to
608 # stop now and register the expected failure.
609 raise _ShouldStop
610 finally:
611 self._subtest = parent
612
613 def _feedErrorsToResult(self, result, errors):
614 for test, exc_info in errors:
615 if isinstance(test, _SubTest):
616 result.addSubTest(test.test_case, test, exc_info)
617 elif exc_info is not None:
618 if issubclass(exc_info[0], self.failureException):
619 result.addFailure(test, exc_info)
620 else:
621 result.addError(test, exc_info)
622
623 def _addExpectedFailure(self, result, exc_info):
624 try:
625 addExpectedFailure = result.addExpectedFailure
626 except AttributeError:
627 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
628 RuntimeWarning)
629 result.addSuccess(self)
630 else:
631 addExpectedFailure(self, exc_info)
632
633 def _addUnexpectedSuccess(self, result):
634 try:
635 addUnexpectedSuccess = result.addUnexpectedSuccess
636 except AttributeError:
637 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
638 RuntimeWarning)
639 # We need to pass an actual exception and traceback to addFailure,
640 # otherwise the legacy result can choke.
641 try:
642 raise _UnexpectedSuccess from None
643 except _UnexpectedSuccess:
644 result.addFailure(self, sys.exc_info())
645 else:
646 addUnexpectedSuccess(self)
Michael Foordb3468f72010-12-19 03:19:47 +0000647
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000648 def run(self, result=None):
649 orig_result = result
650 if result is None:
651 result = self.defaultTestResult()
652 startTestRun = getattr(result, 'startTestRun', None)
653 if startTestRun is not None:
654 startTestRun()
655
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000657
658 testMethod = getattr(self, self._testMethodName)
659 if (getattr(self.__class__, "__unittest_skip__", False) or
660 getattr(testMethod, "__unittest_skip__", False)):
661 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000662 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000663 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
664 or getattr(testMethod, '__unittest_skip_why__', ''))
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100665 self._addSkip(result, self, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000666 finally:
667 result.stopTest(self)
668 return
Robert Collinsed599b72015-08-28 10:34:51 +1200669 expecting_failure_method = getattr(testMethod,
670 "__unittest_expecting_failure__", False)
671 expecting_failure_class = getattr(self,
672 "__unittest_expecting_failure__", False)
673 expecting_failure = expecting_failure_class or expecting_failure_method
Victor Stinner031bd532013-12-09 01:52:50 +0100674 outcome = _Outcome(result)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000675 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100676 self._outcome = outcome
Michael Foordb3468f72010-12-19 03:19:47 +0000677
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100678 with outcome.testPartExecutor(self):
679 self.setUp()
Michael Foordb3468f72010-12-19 03:19:47 +0000680 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100681 outcome.expecting_failure = expecting_failure
682 with outcome.testPartExecutor(self, isTest=True):
683 testMethod()
684 outcome.expecting_failure = False
685 with outcome.testPartExecutor(self):
686 self.tearDown()
Michael Foordb3468f72010-12-19 03:19:47 +0000687
688 self.doCleanups()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100689 for test, reason in outcome.skipped:
690 self._addSkip(result, test, reason)
691 self._feedErrorsToResult(result, outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +0000692 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100693 if expecting_failure:
694 if outcome.expectedFailure:
695 self._addExpectedFailure(result, outcome.expectedFailure)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000696 else:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100697 self._addUnexpectedSuccess(result)
698 else:
699 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400700 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000701 finally:
702 result.stopTest(self)
703 if orig_result is None:
704 stopTestRun = getattr(result, 'stopTestRun', None)
705 if stopTestRun is not None:
706 stopTestRun()
707
Victor Stinner031bd532013-12-09 01:52:50 +0100708 # explicitly break reference cycles:
709 # outcome.errors -> frame -> outcome -> outcome.errors
710 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
711 outcome.errors.clear()
712 outcome.expectedFailure = None
713
714 # clear the outcome, no more needed
715 self._outcome = None
716
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000717 def doCleanups(self):
718 """Execute all cleanup functions. Normally called for you after
719 tearDown."""
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100720 outcome = self._outcome or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000721 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000722 function, args, kwargs = self._cleanups.pop()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100723 with outcome.testPartExecutor(self):
724 function(*args, **kwargs)
Michael Foordb3468f72010-12-19 03:19:47 +0000725
726 # return this for backwards compatibility
Lisa Roach0f221d02018-11-08 18:34:33 -0800727 # even though we no longer use it internally
Michael Foordb3468f72010-12-19 03:19:47 +0000728 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000729
Lisa Roach0f221d02018-11-08 18:34:33 -0800730 @classmethod
731 def doClassCleanups(cls):
732 """Execute all class cleanup functions. Normally called for you after
733 tearDownClass."""
734 cls.tearDown_exceptions = []
735 while cls._class_cleanups:
736 function, args, kwargs = cls._class_cleanups.pop()
737 try:
738 function(*args, **kwargs)
739 except Exception as exc:
740 cls.tearDown_exceptions.append(sys.exc_info())
741
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000742 def __call__(self, *args, **kwds):
743 return self.run(*args, **kwds)
744
745 def debug(self):
746 """Run the test without collecting errors in a TestResult"""
747 self.setUp()
748 getattr(self, self._testMethodName)()
749 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000750 while self._cleanups:
751 function, args, kwargs = self._cleanups.pop(-1)
752 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000753
754 def skipTest(self, reason):
755 """Skip this test."""
756 raise SkipTest(reason)
757
758 def fail(self, msg=None):
759 """Fail immediately, with the given message."""
760 raise self.failureException(msg)
761
762 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000763 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000764 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000765 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000766 raise self.failureException(msg)
767
768 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000769 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000770 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000771 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000772 raise self.failureException(msg)
773
774 def _formatMessage(self, msg, standardMsg):
775 """Honour the longMessage attribute when generating failure messages.
776 If longMessage is False this means:
777 * Use only an explicit message if it is provided
778 * Otherwise use the standard message for the assert
779
780 If longMessage is True:
781 * Use the standard message
782 * If an explicit message is provided, plus ' : ' and the explicit message
783 """
784 if not self.longMessage:
785 return msg or standardMsg
786 if msg is None:
787 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000788 try:
789 # don't switch to '{}' formatting in Python 2.X
790 # it changes the way unicode input is handled
791 return '%s : %s' % (standardMsg, msg)
792 except UnicodeDecodeError:
793 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000794
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300795 def assertRaises(self, expected_exception, *args, **kwargs):
796 """Fail unless an exception of class expected_exception is raised
797 by the callable when invoked with specified positional and
798 keyword arguments. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200799 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000800 deemed to have suffered an error, exactly as for an
801 unexpected exception.
802
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300803 If called with the callable and arguments omitted, will return a
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000804 context object used like this::
805
Michael Foord1c42b122010-02-05 22:58:21 +0000806 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000807 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000808
Ezio Melottib4dc2502011-05-06 15:01:41 +0300809 An optional keyword argument 'msg' can be provided when assertRaises
810 is used as a context object.
811
Michael Foord1c42b122010-02-05 22:58:21 +0000812 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000813 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000814 exception after the assertion::
815
816 with self.assertRaises(SomeException) as cm:
817 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000818 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000819 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000820 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300821 context = _AssertRaisesContext(expected_exception, self)
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200822 try:
823 return context.handle('assertRaises', args, kwargs)
824 finally:
825 # bpo-23890: manually break a reference cycle
826 context = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000827
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300828 def assertWarns(self, expected_warning, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000829 """Fail unless a warning of class warnClass is triggered
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300830 by the callable when invoked with specified positional and
831 keyword arguments. If a different type of warning is
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000832 triggered, it will not be handled: depending on the other
833 warning filtering rules in effect, it might be silenced, printed
834 out, or raised as an exception.
835
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300836 If called with the callable and arguments omitted, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000837 context object used like this::
838
839 with self.assertWarns(SomeWarning):
840 do_something()
841
Ezio Melottib4dc2502011-05-06 15:01:41 +0300842 An optional keyword argument 'msg' can be provided when assertWarns
843 is used as a context object.
844
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000845 The context manager keeps a reference to the first matching
846 warning as the 'warning' attribute; similarly, the 'filename'
847 and 'lineno' attributes give you information about the line
848 of Python code from which the warning was triggered.
849 This allows you to inspect the warning after the assertion::
850
851 with self.assertWarns(SomeWarning) as cm:
852 do_something()
853 the_warning = cm.warning
854 self.assertEqual(the_warning.some_attribute, 147)
855 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300856 context = _AssertWarnsContext(expected_warning, self)
857 return context.handle('assertWarns', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000858
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200859 def assertLogs(self, logger=None, level=None):
860 """Fail unless a log message of level *level* or higher is emitted
861 on *logger_name* or its children. If omitted, *level* defaults to
862 INFO and *logger* defaults to the root logger.
863
864 This method must be used as a context manager, and will yield
865 a recording object with two attributes: `output` and `records`.
866 At the end of the context manager, the `output` attribute will
867 be a list of the matching formatted log messages and the
868 `records` attribute will be a list of the corresponding LogRecord
869 objects.
870
871 Example::
872
873 with self.assertLogs('foo', level='INFO') as cm:
874 logging.getLogger('foo').info('first message')
875 logging.getLogger('foo.bar').error('second message')
876 self.assertEqual(cm.output, ['INFO:foo:first message',
877 'ERROR:foo.bar:second message'])
878 """
879 return _AssertLogsContext(self, logger, level)
880
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000881 def _getAssertEqualityFunc(self, first, second):
882 """Get a detailed comparison function for the types of the two args.
883
884 Returns: A callable accepting (first, second, msg=None) that will
885 raise a failure exception if first != second with a useful human
886 readable error message for those types.
887 """
888 #
889 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
890 # and vice versa. I opted for the conservative approach in case
891 # subclasses are not intended to be compared in detail to their super
892 # class instances using a type equality func. This means testing
893 # subtypes won't automagically use the detailed comparison. Callers
894 # should use their type specific assertSpamEqual method to compare
895 # subclasses if the detailed comparison is desired and appropriate.
896 # See the discussion in http://bugs.python.org/issue2578.
897 #
898 if type(first) is type(second):
899 asserter = self._type_equality_funcs.get(type(first))
900 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500901 if isinstance(asserter, str):
902 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000903 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000904
905 return self._baseAssertEqual
906
907 def _baseAssertEqual(self, first, second, msg=None):
908 """The default assertEqual implementation, not type specific."""
909 if not first == second:
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300910 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000911 msg = self._formatMessage(msg, standardMsg)
912 raise self.failureException(msg)
913
914 def assertEqual(self, first, second, msg=None):
915 """Fail if the two objects are unequal as determined by the '=='
916 operator.
917 """
918 assertion_func = self._getAssertEqualityFunc(first, second)
919 assertion_func(first, second, msg=msg)
920
921 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200922 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000923 operator.
924 """
925 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000926 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
927 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000928 raise self.failureException(msg)
929
Michael Foord321d0592010-11-02 13:44:51 +0000930 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000931 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000932 """Fail if the two objects are unequal as determined by their
933 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000934 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300935 difference between the two objects is more than the given
936 delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000937
938 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000939 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000940
941 If the two objects compare equal then they will automatically
942 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000943 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000944 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000945 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000946 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000947 if delta is not None and places is not None:
948 raise TypeError("specify delta or places not both")
949
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200950 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000951 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200952 if diff <= delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000953 return
954
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200955 standardMsg = '%s != %s within %s delta (%s difference)' % (
956 safe_repr(first),
957 safe_repr(second),
958 safe_repr(delta),
959 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000960 else:
961 if places is None:
962 places = 7
963
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200964 if round(diff, places) == 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000965 return
966
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200967 standardMsg = '%s != %s within %r places (%s difference)' % (
968 safe_repr(first),
969 safe_repr(second),
970 places,
971 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000972 msg = self._formatMessage(msg, standardMsg)
973 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000974
Michael Foord321d0592010-11-02 13:44:51 +0000975 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000976 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000977 """Fail if the two objects are equal as determined by their
978 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000979 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300980 difference between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000981
982 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000983 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000984
985 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000986 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000987 if delta is not None and places is not None:
988 raise TypeError("specify delta or places not both")
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200989 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000990 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200991 if not (first == second) and diff > delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000992 return
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200993 standardMsg = '%s == %s within %s delta (%s difference)' % (
994 safe_repr(first),
995 safe_repr(second),
996 safe_repr(delta),
997 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000998 else:
999 if places is None:
1000 places = 7
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +02001001 if not (first == second) and round(diff, places) != 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +00001002 return
Benjamin Peterson847a4112010-03-14 15:04:17 +00001003 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +00001004 safe_repr(second),
1005 places)
1006
1007 msg = self._formatMessage(msg, standardMsg)
1008 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001009
Michael Foord085dfd32010-06-05 12:17:02 +00001010 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001011 """An equality assertion for ordered sequences (like lists and tuples).
1012
R. David Murrayad13f222010-01-29 22:17:58 +00001013 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001014 which can be indexed, has a length, and has an equality operator.
1015
1016 Args:
1017 seq1: The first sequence to compare.
1018 seq2: The second sequence to compare.
1019 seq_type: The expected datatype of the sequences, or None if no
1020 datatype should be enforced.
1021 msg: Optional message to use on failure instead of a list of
1022 differences.
1023 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -04001024 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001025 seq_type_name = seq_type.__name__
1026 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001027 raise self.failureException('First sequence is not a %s: %s'
1028 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001029 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001030 raise self.failureException('Second sequence is not a %s: %s'
1031 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001032 else:
1033 seq_type_name = "sequence"
1034
1035 differing = None
1036 try:
1037 len1 = len(seq1)
1038 except (TypeError, NotImplementedError):
1039 differing = 'First %s has no length. Non-sequence?' % (
1040 seq_type_name)
1041
1042 if differing is None:
1043 try:
1044 len2 = len(seq2)
1045 except (TypeError, NotImplementedError):
1046 differing = 'Second %s has no length. Non-sequence?' % (
1047 seq_type_name)
1048
1049 if differing is None:
1050 if seq1 == seq2:
1051 return
1052
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001053 differing = '%ss differ: %s != %s\n' % (
1054 (seq_type_name.capitalize(),) +
1055 _common_shorten_repr(seq1, seq2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001056
1057 for i in range(min(len1, len2)):
1058 try:
1059 item1 = seq1[i]
1060 except (TypeError, IndexError, NotImplementedError):
1061 differing += ('\nUnable to index element %d of first %s\n' %
1062 (i, seq_type_name))
1063 break
1064
1065 try:
1066 item2 = seq2[i]
1067 except (TypeError, IndexError, NotImplementedError):
1068 differing += ('\nUnable to index element %d of second %s\n' %
1069 (i, seq_type_name))
1070 break
1071
1072 if item1 != item2:
1073 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001074 ((i,) + _common_shorten_repr(item1, item2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001075 break
1076 else:
1077 if (len1 == len2 and seq_type is None and
1078 type(seq1) != type(seq2)):
1079 # The sequences are the same, but have differing types.
1080 return
1081
1082 if len1 > len2:
1083 differing += ('\nFirst %s contains %d additional '
1084 'elements.\n' % (seq_type_name, len1 - len2))
1085 try:
1086 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001087 (len2, safe_repr(seq1[len2])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001088 except (TypeError, IndexError, NotImplementedError):
1089 differing += ('Unable to index element %d '
1090 'of first %s\n' % (len2, seq_type_name))
1091 elif len1 < len2:
1092 differing += ('\nSecond %s contains %d additional '
1093 'elements.\n' % (seq_type_name, len2 - len1))
1094 try:
1095 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001096 (len1, safe_repr(seq2[len1])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001097 except (TypeError, IndexError, NotImplementedError):
1098 differing += ('Unable to index element %d '
1099 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +00001100 standardMsg = differing
1101 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001102 difflib.ndiff(pprint.pformat(seq1).splitlines(),
1103 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +00001104
1105 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001106 msg = self._formatMessage(msg, standardMsg)
1107 self.fail(msg)
1108
Michael Foord085dfd32010-06-05 12:17:02 +00001109 def _truncateMessage(self, message, diff):
1110 max_diff = self.maxDiff
1111 if max_diff is None or len(diff) <= max_diff:
1112 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +00001113 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +00001114
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001115 def assertListEqual(self, list1, list2, msg=None):
1116 """A list-specific equality assertion.
1117
1118 Args:
1119 list1: The first list to compare.
1120 list2: The second list to compare.
1121 msg: Optional message to use on failure instead of a list of
1122 differences.
1123
1124 """
1125 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
1126
1127 def assertTupleEqual(self, tuple1, tuple2, msg=None):
1128 """A tuple-specific equality assertion.
1129
1130 Args:
1131 tuple1: The first tuple to compare.
1132 tuple2: The second tuple to compare.
1133 msg: Optional message to use on failure instead of a list of
1134 differences.
1135 """
1136 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1137
1138 def assertSetEqual(self, set1, set2, msg=None):
1139 """A set-specific equality assertion.
1140
1141 Args:
1142 set1: The first set to compare.
1143 set2: The second set to compare.
1144 msg: Optional message to use on failure instead of a list of
1145 differences.
1146
Michael Foord91c9da32010-03-20 17:21:27 +00001147 assertSetEqual uses ducktyping to support different types of sets, and
1148 is optimized for sets specifically (parameters must support a
1149 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001150 """
1151 try:
1152 difference1 = set1.difference(set2)
1153 except TypeError as e:
1154 self.fail('invalid type when attempting set difference: %s' % e)
1155 except AttributeError as e:
1156 self.fail('first argument does not support set difference: %s' % e)
1157
1158 try:
1159 difference2 = set2.difference(set1)
1160 except TypeError as e:
1161 self.fail('invalid type when attempting set difference: %s' % e)
1162 except AttributeError as e:
1163 self.fail('second argument does not support set difference: %s' % e)
1164
1165 if not (difference1 or difference2):
1166 return
1167
1168 lines = []
1169 if difference1:
1170 lines.append('Items in the first set but not the second:')
1171 for item in difference1:
1172 lines.append(repr(item))
1173 if difference2:
1174 lines.append('Items in the second set but not the first:')
1175 for item in difference2:
1176 lines.append(repr(item))
1177
1178 standardMsg = '\n'.join(lines)
1179 self.fail(self._formatMessage(msg, standardMsg))
1180
1181 def assertIn(self, member, container, msg=None):
1182 """Just like self.assertTrue(a in b), but with a nicer default message."""
1183 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001184 standardMsg = '%s not found in %s' % (safe_repr(member),
1185 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001186 self.fail(self._formatMessage(msg, standardMsg))
1187
1188 def assertNotIn(self, member, container, msg=None):
1189 """Just like self.assertTrue(a not in b), but with a nicer default message."""
1190 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001191 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1192 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001193 self.fail(self._formatMessage(msg, standardMsg))
1194
1195 def assertIs(self, expr1, expr2, msg=None):
1196 """Just like self.assertTrue(a is b), but with a nicer default message."""
1197 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001198 standardMsg = '%s is not %s' % (safe_repr(expr1),
1199 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001200 self.fail(self._formatMessage(msg, standardMsg))
1201
1202 def assertIsNot(self, expr1, expr2, msg=None):
1203 """Just like self.assertTrue(a is not b), but with a nicer default message."""
1204 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001205 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001206 self.fail(self._formatMessage(msg, standardMsg))
1207
1208 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001209 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1210 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001211
1212 if d1 != d2:
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001213 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
Michael Foord085dfd32010-06-05 12:17:02 +00001214 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001215 pprint.pformat(d1).splitlines(),
1216 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +00001217 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001218 self.fail(self._formatMessage(msg, standardMsg))
1219
Ezio Melotti0f535012011-04-03 18:02:13 +03001220 def assertDictContainsSubset(self, subset, dictionary, msg=None):
1221 """Checks whether dictionary is a superset of subset."""
1222 warnings.warn('assertDictContainsSubset is deprecated',
1223 DeprecationWarning)
1224 missing = []
1225 mismatched = []
1226 for key, value in subset.items():
1227 if key not in dictionary:
1228 missing.append(key)
1229 elif value != dictionary[key]:
1230 mismatched.append('%s, expected: %s, actual: %s' %
1231 (safe_repr(key), safe_repr(value),
1232 safe_repr(dictionary[key])))
1233
1234 if not (missing or mismatched):
1235 return
1236
1237 standardMsg = ''
1238 if missing:
1239 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1240 missing)
1241 if mismatched:
1242 if standardMsg:
1243 standardMsg += '; '
1244 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1245
1246 self.fail(self._formatMessage(msg, standardMsg))
1247
1248
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001249 def assertCountEqual(self, first, second, msg=None):
jkleint39baace2019-04-23 01:34:29 -07001250 """Asserts that two iterables have the same elements, the same number of
1251 times, without regard to order.
Michael Foord8442a602010-03-20 16:58:04 +00001252
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001253 self.assertEqual(Counter(list(first)),
1254 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001255
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001256 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001257 - [0, 1, 1] and [1, 0, 1] compare equal.
1258 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001259
Michael Foord8442a602010-03-20 16:58:04 +00001260 """
Michael Foorde180d392011-01-28 19:51:48 +00001261 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001262 try:
Michael Foorde180d392011-01-28 19:51:48 +00001263 first = collections.Counter(first_seq)
1264 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001265 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001266 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001267 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001268 else:
Michael Foorde180d392011-01-28 19:51:48 +00001269 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001270 return
Michael Foorde180d392011-01-28 19:51:48 +00001271 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001272
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001273 if differences:
1274 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001275 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001276 diffMsg = '\n'.join(lines)
1277 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1278 msg = self._formatMessage(msg, standardMsg)
1279 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001280
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001281 def assertMultiLineEqual(self, first, second, msg=None):
1282 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001283 self.assertIsInstance(first, str, 'First argument is not a string')
1284 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001285
1286 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001287 # don't use difflib if the strings are too long
1288 if (len(first) > self._diffThreshold or
1289 len(second) > self._diffThreshold):
1290 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001291 firstlines = first.splitlines(keepends=True)
1292 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001293 if len(firstlines) == 1 and first.strip('\r\n') == first:
1294 firstlines = [first + '\n']
1295 secondlines = [second + '\n']
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001296 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Michael Foordc653ce32010-07-10 13:52:22 +00001297 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001298 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001299 self.fail(self._formatMessage(msg, standardMsg))
1300
1301 def assertLess(self, a, b, msg=None):
1302 """Just like self.assertTrue(a < b), but with a nicer default message."""
1303 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001304 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001305 self.fail(self._formatMessage(msg, standardMsg))
1306
1307 def assertLessEqual(self, a, b, msg=None):
1308 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1309 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001310 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001311 self.fail(self._formatMessage(msg, standardMsg))
1312
1313 def assertGreater(self, a, b, msg=None):
1314 """Just like self.assertTrue(a > b), but with a nicer default message."""
1315 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001316 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001317 self.fail(self._formatMessage(msg, standardMsg))
1318
1319 def assertGreaterEqual(self, a, b, msg=None):
1320 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1321 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001322 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001323 self.fail(self._formatMessage(msg, standardMsg))
1324
1325 def assertIsNone(self, obj, msg=None):
1326 """Same as self.assertTrue(obj is None), with a nicer default message."""
1327 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001328 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001329 self.fail(self._formatMessage(msg, standardMsg))
1330
1331 def assertIsNotNone(self, obj, msg=None):
1332 """Included for symmetry with assertIsNone."""
1333 if obj is None:
1334 standardMsg = 'unexpectedly None'
1335 self.fail(self._formatMessage(msg, standardMsg))
1336
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001337 def assertIsInstance(self, obj, cls, msg=None):
1338 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1339 default message."""
1340 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001341 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001342 self.fail(self._formatMessage(msg, standardMsg))
1343
1344 def assertNotIsInstance(self, obj, cls, msg=None):
1345 """Included for symmetry with assertIsInstance."""
1346 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001347 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001348 self.fail(self._formatMessage(msg, standardMsg))
1349
Ezio Melottied3a7d22010-12-01 02:32:32 +00001350 def assertRaisesRegex(self, expected_exception, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001351 *args, **kwargs):
Ezio Melottied3a7d22010-12-01 02:32:32 +00001352 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001353
1354 Args:
1355 expected_exception: Exception class expected to be raised.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001356 expected_regex: Regex (re.Pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001357 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001358 args: Function to be called and extra positional args.
1359 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001360 msg: Optional message used in case of failure. Can only be used
1361 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001362 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001363 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1364 return context.handle('assertRaisesRegex', args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001365
Ezio Melottied3a7d22010-12-01 02:32:32 +00001366 def assertWarnsRegex(self, expected_warning, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001367 *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001368 """Asserts that the message in a triggered warning matches a regexp.
1369 Basic functioning is similar to assertWarns() with the addition
1370 that only warnings whose messages also match the regular expression
1371 are considered successful matches.
1372
1373 Args:
1374 expected_warning: Warning class expected to be triggered.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001375 expected_regex: Regex (re.Pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001376 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001377 args: Function to be called and extra positional args.
1378 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001379 msg: Optional message used in case of failure. Can only be used
1380 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001381 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001382 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1383 return context.handle('assertWarnsRegex', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001384
Ezio Melottied3a7d22010-12-01 02:32:32 +00001385 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001386 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001387 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001388 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001389 expected_regex = re.compile(expected_regex)
1390 if not expected_regex.search(text):
Robert Collinsbe6caca2015-08-20 11:13:09 +12001391 standardMsg = "Regex didn't match: %r not found in %r" % (
1392 expected_regex.pattern, text)
1393 # _formatMessage ensures the longMessage option is respected
1394 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001395 raise self.failureException(msg)
1396
Ezio Melotti8f776302010-12-10 02:32:05 +00001397 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001398 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001399 if isinstance(unexpected_regex, (str, bytes)):
1400 unexpected_regex = re.compile(unexpected_regex)
1401 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001402 if match:
Robert Collinsbe6caca2015-08-20 11:13:09 +12001403 standardMsg = 'Regex matched: %r matches %r in %r' % (
1404 text[match.start() : match.end()],
1405 unexpected_regex.pattern,
1406 text)
1407 # _formatMessage ensures the longMessage option is respected
1408 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001409 raise self.failureException(msg)
1410
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001411
Ezio Melottied3a7d22010-12-01 02:32:32 +00001412 def _deprecate(original_func):
1413 def deprecated_func(*args, **kwargs):
1414 warnings.warn(
1415 'Please use {0} instead.'.format(original_func.__name__),
1416 DeprecationWarning, 2)
1417 return original_func(*args, **kwargs)
1418 return deprecated_func
1419
Ezio Melotti361467e2011-04-03 17:37:58 +03001420 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001421 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1422 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1423 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1424 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1425 failUnless = assert_ = _deprecate(assertTrue)
1426 failUnlessRaises = _deprecate(assertRaises)
1427 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001428 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1429 assertRegexpMatches = _deprecate(assertRegex)
Robert Collinsbe6caca2015-08-20 11:13:09 +12001430 assertNotRegexpMatches = _deprecate(assertNotRegex)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001431
1432
1433
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001434class FunctionTestCase(TestCase):
1435 """A test case that wraps a test function.
1436
1437 This is useful for slipping pre-existing test functions into the
1438 unittest framework. Optionally, set-up and tidy-up functions can be
1439 supplied. As with TestCase, the tidy-up ('tearDown') function will
1440 always be called if the set-up ('setUp') function ran successfully.
1441 """
1442
1443 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1444 super(FunctionTestCase, self).__init__()
1445 self._setUpFunc = setUp
1446 self._tearDownFunc = tearDown
1447 self._testFunc = testFunc
1448 self._description = description
1449
1450 def setUp(self):
1451 if self._setUpFunc is not None:
1452 self._setUpFunc()
1453
1454 def tearDown(self):
1455 if self._tearDownFunc is not None:
1456 self._tearDownFunc()
1457
1458 def runTest(self):
1459 self._testFunc()
1460
1461 def id(self):
1462 return self._testFunc.__name__
1463
1464 def __eq__(self, other):
1465 if not isinstance(other, self.__class__):
1466 return NotImplemented
1467
1468 return self._setUpFunc == other._setUpFunc and \
1469 self._tearDownFunc == other._tearDownFunc and \
1470 self._testFunc == other._testFunc and \
1471 self._description == other._description
1472
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001473 def __hash__(self):
1474 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1475 self._testFunc, self._description))
1476
1477 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001478 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001479 self._testFunc.__name__)
1480
1481 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001482 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001483 self._testFunc)
1484
1485 def shortDescription(self):
1486 if self._description is not None:
1487 return self._description
1488 doc = self._testFunc.__doc__
1489 return doc and doc.split("\n")[0].strip() or None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001490
1491
1492class _SubTest(TestCase):
1493
1494 def __init__(self, test_case, message, params):
1495 super().__init__()
1496 self._message = message
1497 self.test_case = test_case
1498 self.params = params
1499 self.failureException = test_case.failureException
1500
1501 def runTest(self):
1502 raise NotImplementedError("subtests cannot be run directly")
1503
1504 def _subDescription(self):
1505 parts = []
Berker Peksag16ea19f2016-09-21 19:34:15 +03001506 if self._message is not _subtest_msg_sentinel:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001507 parts.append("[{}]".format(self._message))
1508 if self.params:
1509 params_desc = ', '.join(
1510 "{}={!r}".format(k, v)
Serhiy Storchaka48fbe522017-06-23 21:47:39 +03001511 for (k, v) in self.params.items())
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001512 parts.append("({})".format(params_desc))
1513 return " ".join(parts) or '(<subtest>)'
1514
1515 def id(self):
1516 return "{} {}".format(self.test_case.id(), self._subDescription())
1517
1518 def shortDescription(self):
1519 """Returns a one-line description of the subtest, or None if no
1520 description has been provided.
1521 """
1522 return self.test_case.shortDescription()
1523
1524 def __str__(self):
1525 return "{} {}".format(self.test_case, self._subDescription())