blob: c0170d182573cb3af5bd97bc87f9b846161e3315 [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
445 def addCleanup(self, function, *args, **kwargs):
446 """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)."""
451 self._cleanups.append((function, args, kwargs))
452
453 def setUp(self):
454 "Hook method for setting up the test fixture before exercising it."
455 pass
456
457 def tearDown(self):
458 "Hook method for deconstructing the test fixture after testing it."
459 pass
460
Benjamin Peterson847a4112010-03-14 15:04:17 +0000461 @classmethod
462 def setUpClass(cls):
463 "Hook method for setting up class fixture before running tests in the class."
464
465 @classmethod
466 def tearDownClass(cls):
467 "Hook method for deconstructing the class fixture after running all tests in the class."
468
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000469 def countTestCases(self):
470 return 1
471
472 def defaultTestResult(self):
473 return result.TestResult()
474
475 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000476 """Returns a one-line description of the test, or None if no
477 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000478
Michael Foord34c94622010-02-10 15:51:42 +0000479 The default implementation of this method returns the first line of
480 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000481 """
Michael Foord34c94622010-02-10 15:51:42 +0000482 doc = self._testMethodDoc
483 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000484
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000485
486 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000487 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000488
489 def __eq__(self, other):
490 if type(self) is not type(other):
491 return NotImplemented
492
493 return self._testMethodName == other._testMethodName
494
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000495 def __hash__(self):
496 return hash((type(self), self._testMethodName))
497
498 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000499 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000500
501 def __repr__(self):
502 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000503 (strclass(self.__class__), self._testMethodName)
504
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100505 def _addSkip(self, result, test_case, reason):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000506 addSkip = getattr(result, 'addSkip', None)
507 if addSkip is not None:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100508 addSkip(test_case, reason)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000509 else:
510 warnings.warn("TestResult has no addSkip method, skips not reported",
511 RuntimeWarning, 2)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100512 result.addSuccess(test_case)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000513
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100514 @contextlib.contextmanager
Berker Peksag16ea19f2016-09-21 19:34:15 +0300515 def subTest(self, msg=_subtest_msg_sentinel, **params):
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100516 """Return a context manager that will return the enclosed block
517 of code in a subtest identified by the optional message and
518 keyword parameters. A failure in the subtest marks the test
519 case as failed but resumes execution at the end of the enclosed
520 block, allowing further test code to be executed.
521 """
522 if not self._outcome.result_supports_subtests:
523 yield
524 return
525 parent = self._subtest
526 if parent is None:
Serhiy Storchaka48fbe522017-06-23 21:47:39 +0300527 params_map = _OrderedChainMap(params)
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100528 else:
529 params_map = parent.params.new_child(params)
530 self._subtest = _SubTest(self, msg, params_map)
Michael Foordb3468f72010-12-19 03:19:47 +0000531 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100532 with self._outcome.testPartExecutor(self._subtest, isTest=True):
533 yield
534 if not self._outcome.success:
535 result = self._outcome.result
536 if result is not None and result.failfast:
537 raise _ShouldStop
538 elif self._outcome.expectedFailure:
539 # If the test is expecting a failure, we really want to
540 # stop now and register the expected failure.
541 raise _ShouldStop
542 finally:
543 self._subtest = parent
544
545 def _feedErrorsToResult(self, result, errors):
546 for test, exc_info in errors:
547 if isinstance(test, _SubTest):
548 result.addSubTest(test.test_case, test, exc_info)
549 elif exc_info is not None:
550 if issubclass(exc_info[0], self.failureException):
551 result.addFailure(test, exc_info)
552 else:
553 result.addError(test, exc_info)
554
555 def _addExpectedFailure(self, result, exc_info):
556 try:
557 addExpectedFailure = result.addExpectedFailure
558 except AttributeError:
559 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
560 RuntimeWarning)
561 result.addSuccess(self)
562 else:
563 addExpectedFailure(self, exc_info)
564
565 def _addUnexpectedSuccess(self, result):
566 try:
567 addUnexpectedSuccess = result.addUnexpectedSuccess
568 except AttributeError:
569 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
570 RuntimeWarning)
571 # We need to pass an actual exception and traceback to addFailure,
572 # otherwise the legacy result can choke.
573 try:
574 raise _UnexpectedSuccess from None
575 except _UnexpectedSuccess:
576 result.addFailure(self, sys.exc_info())
577 else:
578 addUnexpectedSuccess(self)
Michael Foordb3468f72010-12-19 03:19:47 +0000579
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000580 def run(self, result=None):
581 orig_result = result
582 if result is None:
583 result = self.defaultTestResult()
584 startTestRun = getattr(result, 'startTestRun', None)
585 if startTestRun is not None:
586 startTestRun()
587
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000588 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000589
590 testMethod = getattr(self, self._testMethodName)
591 if (getattr(self.__class__, "__unittest_skip__", False) or
592 getattr(testMethod, "__unittest_skip__", False)):
593 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000594 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000595 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
596 or getattr(testMethod, '__unittest_skip_why__', ''))
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100597 self._addSkip(result, self, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000598 finally:
599 result.stopTest(self)
600 return
Robert Collinsed599b72015-08-28 10:34:51 +1200601 expecting_failure_method = getattr(testMethod,
602 "__unittest_expecting_failure__", False)
603 expecting_failure_class = getattr(self,
604 "__unittest_expecting_failure__", False)
605 expecting_failure = expecting_failure_class or expecting_failure_method
Victor Stinner031bd532013-12-09 01:52:50 +0100606 outcome = _Outcome(result)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000607 try:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100608 self._outcome = outcome
Michael Foordb3468f72010-12-19 03:19:47 +0000609
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100610 with outcome.testPartExecutor(self):
611 self.setUp()
Michael Foordb3468f72010-12-19 03:19:47 +0000612 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100613 outcome.expecting_failure = expecting_failure
614 with outcome.testPartExecutor(self, isTest=True):
615 testMethod()
616 outcome.expecting_failure = False
617 with outcome.testPartExecutor(self):
618 self.tearDown()
Michael Foordb3468f72010-12-19 03:19:47 +0000619
620 self.doCleanups()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100621 for test, reason in outcome.skipped:
622 self._addSkip(result, test, reason)
623 self._feedErrorsToResult(result, outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +0000624 if outcome.success:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100625 if expecting_failure:
626 if outcome.expectedFailure:
627 self._addExpectedFailure(result, outcome.expectedFailure)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000628 else:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100629 self._addUnexpectedSuccess(result)
630 else:
631 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400632 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000633 finally:
634 result.stopTest(self)
635 if orig_result is None:
636 stopTestRun = getattr(result, 'stopTestRun', None)
637 if stopTestRun is not None:
638 stopTestRun()
639
Victor Stinner031bd532013-12-09 01:52:50 +0100640 # explicitly break reference cycles:
641 # outcome.errors -> frame -> outcome -> outcome.errors
642 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
643 outcome.errors.clear()
644 outcome.expectedFailure = None
645
646 # clear the outcome, no more needed
647 self._outcome = None
648
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000649 def doCleanups(self):
650 """Execute all cleanup functions. Normally called for you after
651 tearDown."""
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100652 outcome = self._outcome or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000653 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000654 function, args, kwargs = self._cleanups.pop()
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +0100655 with outcome.testPartExecutor(self):
656 function(*args, **kwargs)
Michael Foordb3468f72010-12-19 03:19:47 +0000657
658 # return this for backwards compatibility
659 # even though we no longer us it internally
660 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000661
662 def __call__(self, *args, **kwds):
663 return self.run(*args, **kwds)
664
665 def debug(self):
666 """Run the test without collecting errors in a TestResult"""
667 self.setUp()
668 getattr(self, self._testMethodName)()
669 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000670 while self._cleanups:
671 function, args, kwargs = self._cleanups.pop(-1)
672 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000673
674 def skipTest(self, reason):
675 """Skip this test."""
676 raise SkipTest(reason)
677
678 def fail(self, msg=None):
679 """Fail immediately, with the given message."""
680 raise self.failureException(msg)
681
682 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000683 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000684 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000685 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000686 raise self.failureException(msg)
687
688 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000689 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000690 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000691 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000692 raise self.failureException(msg)
693
694 def _formatMessage(self, msg, standardMsg):
695 """Honour the longMessage attribute when generating failure messages.
696 If longMessage is False this means:
697 * Use only an explicit message if it is provided
698 * Otherwise use the standard message for the assert
699
700 If longMessage is True:
701 * Use the standard message
702 * If an explicit message is provided, plus ' : ' and the explicit message
703 """
704 if not self.longMessage:
705 return msg or standardMsg
706 if msg is None:
707 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000708 try:
709 # don't switch to '{}' formatting in Python 2.X
710 # it changes the way unicode input is handled
711 return '%s : %s' % (standardMsg, msg)
712 except UnicodeDecodeError:
713 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000714
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300715 def assertRaises(self, expected_exception, *args, **kwargs):
716 """Fail unless an exception of class expected_exception is raised
717 by the callable when invoked with specified positional and
718 keyword arguments. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200719 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000720 deemed to have suffered an error, exactly as for an
721 unexpected exception.
722
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300723 If called with the callable and arguments omitted, will return a
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000724 context object used like this::
725
Michael Foord1c42b122010-02-05 22:58:21 +0000726 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000727 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000728
Ezio Melottib4dc2502011-05-06 15:01:41 +0300729 An optional keyword argument 'msg' can be provided when assertRaises
730 is used as a context object.
731
Michael Foord1c42b122010-02-05 22:58:21 +0000732 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000733 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000734 exception after the assertion::
735
736 with self.assertRaises(SomeException) as cm:
737 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000738 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000739 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000740 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300741 context = _AssertRaisesContext(expected_exception, self)
Victor Stinnerbbd3cf82017-03-28 00:56:28 +0200742 try:
743 return context.handle('assertRaises', args, kwargs)
744 finally:
745 # bpo-23890: manually break a reference cycle
746 context = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000747
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300748 def assertWarns(self, expected_warning, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000749 """Fail unless a warning of class warnClass is triggered
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300750 by the callable when invoked with specified positional and
751 keyword arguments. If a different type of warning is
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000752 triggered, it will not be handled: depending on the other
753 warning filtering rules in effect, it might be silenced, printed
754 out, or raised as an exception.
755
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300756 If called with the callable and arguments omitted, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000757 context object used like this::
758
759 with self.assertWarns(SomeWarning):
760 do_something()
761
Ezio Melottib4dc2502011-05-06 15:01:41 +0300762 An optional keyword argument 'msg' can be provided when assertWarns
763 is used as a context object.
764
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000765 The context manager keeps a reference to the first matching
766 warning as the 'warning' attribute; similarly, the 'filename'
767 and 'lineno' attributes give you information about the line
768 of Python code from which the warning was triggered.
769 This allows you to inspect the warning after the assertion::
770
771 with self.assertWarns(SomeWarning) as cm:
772 do_something()
773 the_warning = cm.warning
774 self.assertEqual(the_warning.some_attribute, 147)
775 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +0300776 context = _AssertWarnsContext(expected_warning, self)
777 return context.handle('assertWarns', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000778
Antoine Pitrou0715b9f2013-09-14 19:45:47 +0200779 def assertLogs(self, logger=None, level=None):
780 """Fail unless a log message of level *level* or higher is emitted
781 on *logger_name* or its children. If omitted, *level* defaults to
782 INFO and *logger* defaults to the root logger.
783
784 This method must be used as a context manager, and will yield
785 a recording object with two attributes: `output` and `records`.
786 At the end of the context manager, the `output` attribute will
787 be a list of the matching formatted log messages and the
788 `records` attribute will be a list of the corresponding LogRecord
789 objects.
790
791 Example::
792
793 with self.assertLogs('foo', level='INFO') as cm:
794 logging.getLogger('foo').info('first message')
795 logging.getLogger('foo.bar').error('second message')
796 self.assertEqual(cm.output, ['INFO:foo:first message',
797 'ERROR:foo.bar:second message'])
798 """
799 return _AssertLogsContext(self, logger, level)
800
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000801 def _getAssertEqualityFunc(self, first, second):
802 """Get a detailed comparison function for the types of the two args.
803
804 Returns: A callable accepting (first, second, msg=None) that will
805 raise a failure exception if first != second with a useful human
806 readable error message for those types.
807 """
808 #
809 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
810 # and vice versa. I opted for the conservative approach in case
811 # subclasses are not intended to be compared in detail to their super
812 # class instances using a type equality func. This means testing
813 # subtypes won't automagically use the detailed comparison. Callers
814 # should use their type specific assertSpamEqual method to compare
815 # subclasses if the detailed comparison is desired and appropriate.
816 # See the discussion in http://bugs.python.org/issue2578.
817 #
818 if type(first) is type(second):
819 asserter = self._type_equality_funcs.get(type(first))
820 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500821 if isinstance(asserter, str):
822 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000823 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000824
825 return self._baseAssertEqual
826
827 def _baseAssertEqual(self, first, second, msg=None):
828 """The default assertEqual implementation, not type specific."""
829 if not first == second:
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300830 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000831 msg = self._formatMessage(msg, standardMsg)
832 raise self.failureException(msg)
833
834 def assertEqual(self, first, second, msg=None):
835 """Fail if the two objects are unequal as determined by the '=='
836 operator.
837 """
838 assertion_func = self._getAssertEqualityFunc(first, second)
839 assertion_func(first, second, msg=msg)
840
841 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200842 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000843 operator.
844 """
845 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000846 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
847 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000848 raise self.failureException(msg)
849
Michael Foord321d0592010-11-02 13:44:51 +0000850 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000851 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000852 """Fail if the two objects are unequal as determined by their
853 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000854 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300855 difference between the two objects is more than the given
856 delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000857
858 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000859 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000860
861 If the two objects compare equal then they will automatically
862 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000863 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000864 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000865 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000866 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000867 if delta is not None and places is not None:
868 raise TypeError("specify delta or places not both")
869
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200870 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000871 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200872 if diff <= delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000873 return
874
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200875 standardMsg = '%s != %s within %s delta (%s difference)' % (
876 safe_repr(first),
877 safe_repr(second),
878 safe_repr(delta),
879 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000880 else:
881 if places is None:
882 places = 7
883
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200884 if round(diff, places) == 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000885 return
886
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200887 standardMsg = '%s != %s within %r places (%s difference)' % (
888 safe_repr(first),
889 safe_repr(second),
890 places,
891 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000892 msg = self._formatMessage(msg, standardMsg)
893 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000894
Michael Foord321d0592010-11-02 13:44:51 +0000895 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000896 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000897 """Fail if the two objects are equal as determined by their
898 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000899 (default 7) and comparing to zero, or by comparing that the
Ron032a6482017-10-18 20:01:23 +0300900 difference between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000901
902 Note that decimal places (from zero) are usually not the same
Martin Pantereb995702016-07-28 01:11:04 +0000903 as significant digits (measured from the most significant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000904
905 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000906 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000907 if delta is not None and places is not None:
908 raise TypeError("specify delta or places not both")
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200909 diff = abs(first - second)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000910 if delta is not None:
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200911 if not (first == second) and diff > delta:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000912 return
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200913 standardMsg = '%s == %s within %s delta (%s difference)' % (
914 safe_repr(first),
915 safe_repr(second),
916 safe_repr(delta),
917 safe_repr(diff))
Benjamin Petersonb48af542010-04-11 20:43:16 +0000918 else:
919 if places is None:
920 places = 7
Giampaolo Rodola5d7a8d02017-05-01 18:18:56 +0200921 if not (first == second) and round(diff, places) != 0:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000922 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000923 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000924 safe_repr(second),
925 places)
926
927 msg = self._formatMessage(msg, standardMsg)
928 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000929
Michael Foord085dfd32010-06-05 12:17:02 +0000930 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000931 """An equality assertion for ordered sequences (like lists and tuples).
932
R. David Murrayad13f222010-01-29 22:17:58 +0000933 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000934 which can be indexed, has a length, and has an equality operator.
935
936 Args:
937 seq1: The first sequence to compare.
938 seq2: The second sequence to compare.
939 seq_type: The expected datatype of the sequences, or None if no
940 datatype should be enforced.
941 msg: Optional message to use on failure instead of a list of
942 differences.
943 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400944 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000945 seq_type_name = seq_type.__name__
946 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000947 raise self.failureException('First sequence is not a %s: %s'
948 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000949 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000950 raise self.failureException('Second sequence is not a %s: %s'
951 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000952 else:
953 seq_type_name = "sequence"
954
955 differing = None
956 try:
957 len1 = len(seq1)
958 except (TypeError, NotImplementedError):
959 differing = 'First %s has no length. Non-sequence?' % (
960 seq_type_name)
961
962 if differing is None:
963 try:
964 len2 = len(seq2)
965 except (TypeError, NotImplementedError):
966 differing = 'Second %s has no length. Non-sequence?' % (
967 seq_type_name)
968
969 if differing is None:
970 if seq1 == seq2:
971 return
972
Serhiy Storchaka77622f52013-09-23 23:07:00 +0300973 differing = '%ss differ: %s != %s\n' % (
974 (seq_type_name.capitalize(),) +
975 _common_shorten_repr(seq1, seq2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000976
977 for i in range(min(len1, len2)):
978 try:
979 item1 = seq1[i]
980 except (TypeError, IndexError, NotImplementedError):
981 differing += ('\nUnable to index element %d of first %s\n' %
982 (i, seq_type_name))
983 break
984
985 try:
986 item2 = seq2[i]
987 except (TypeError, IndexError, NotImplementedError):
988 differing += ('\nUnable to index element %d of second %s\n' %
989 (i, seq_type_name))
990 break
991
992 if item1 != item2:
993 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +0300994 ((i,) + _common_shorten_repr(item1, item2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000995 break
996 else:
997 if (len1 == len2 and seq_type is None and
998 type(seq1) != type(seq2)):
999 # The sequences are the same, but have differing types.
1000 return
1001
1002 if len1 > len2:
1003 differing += ('\nFirst %s contains %d additional '
1004 'elements.\n' % (seq_type_name, len1 - len2))
1005 try:
1006 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001007 (len2, safe_repr(seq1[len2])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001008 except (TypeError, IndexError, NotImplementedError):
1009 differing += ('Unable to index element %d '
1010 'of first %s\n' % (len2, seq_type_name))
1011 elif len1 < len2:
1012 differing += ('\nSecond %s contains %d additional '
1013 'elements.\n' % (seq_type_name, len2 - len1))
1014 try:
1015 differing += ('First extra element %d:\n%s\n' %
Serhiy Storchaka685fbed2016-04-25 08:58:25 +03001016 (len1, safe_repr(seq2[len1])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001017 except (TypeError, IndexError, NotImplementedError):
1018 differing += ('Unable to index element %d '
1019 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +00001020 standardMsg = differing
1021 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001022 difflib.ndiff(pprint.pformat(seq1).splitlines(),
1023 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +00001024
1025 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001026 msg = self._formatMessage(msg, standardMsg)
1027 self.fail(msg)
1028
Michael Foord085dfd32010-06-05 12:17:02 +00001029 def _truncateMessage(self, message, diff):
1030 max_diff = self.maxDiff
1031 if max_diff is None or len(diff) <= max_diff:
1032 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +00001033 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +00001034
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001035 def assertListEqual(self, list1, list2, msg=None):
1036 """A list-specific equality assertion.
1037
1038 Args:
1039 list1: The first list to compare.
1040 list2: The second list to compare.
1041 msg: Optional message to use on failure instead of a list of
1042 differences.
1043
1044 """
1045 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
1046
1047 def assertTupleEqual(self, tuple1, tuple2, msg=None):
1048 """A tuple-specific equality assertion.
1049
1050 Args:
1051 tuple1: The first tuple to compare.
1052 tuple2: The second tuple to compare.
1053 msg: Optional message to use on failure instead of a list of
1054 differences.
1055 """
1056 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1057
1058 def assertSetEqual(self, set1, set2, msg=None):
1059 """A set-specific equality assertion.
1060
1061 Args:
1062 set1: The first set to compare.
1063 set2: The second set to compare.
1064 msg: Optional message to use on failure instead of a list of
1065 differences.
1066
Michael Foord91c9da32010-03-20 17:21:27 +00001067 assertSetEqual uses ducktyping to support different types of sets, and
1068 is optimized for sets specifically (parameters must support a
1069 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001070 """
1071 try:
1072 difference1 = set1.difference(set2)
1073 except TypeError as e:
1074 self.fail('invalid type when attempting set difference: %s' % e)
1075 except AttributeError as e:
1076 self.fail('first argument does not support set difference: %s' % e)
1077
1078 try:
1079 difference2 = set2.difference(set1)
1080 except TypeError as e:
1081 self.fail('invalid type when attempting set difference: %s' % e)
1082 except AttributeError as e:
1083 self.fail('second argument does not support set difference: %s' % e)
1084
1085 if not (difference1 or difference2):
1086 return
1087
1088 lines = []
1089 if difference1:
1090 lines.append('Items in the first set but not the second:')
1091 for item in difference1:
1092 lines.append(repr(item))
1093 if difference2:
1094 lines.append('Items in the second set but not the first:')
1095 for item in difference2:
1096 lines.append(repr(item))
1097
1098 standardMsg = '\n'.join(lines)
1099 self.fail(self._formatMessage(msg, standardMsg))
1100
1101 def assertIn(self, member, container, msg=None):
1102 """Just like self.assertTrue(a in b), but with a nicer default message."""
1103 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001104 standardMsg = '%s not found in %s' % (safe_repr(member),
1105 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001106 self.fail(self._formatMessage(msg, standardMsg))
1107
1108 def assertNotIn(self, member, container, msg=None):
1109 """Just like self.assertTrue(a not in b), but with a nicer default message."""
1110 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001111 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1112 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001113 self.fail(self._formatMessage(msg, standardMsg))
1114
1115 def assertIs(self, expr1, expr2, msg=None):
1116 """Just like self.assertTrue(a is b), but with a nicer default message."""
1117 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001118 standardMsg = '%s is not %s' % (safe_repr(expr1),
1119 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001120 self.fail(self._formatMessage(msg, standardMsg))
1121
1122 def assertIsNot(self, expr1, expr2, msg=None):
1123 """Just like self.assertTrue(a is not b), but with a nicer default message."""
1124 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001125 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001126 self.fail(self._formatMessage(msg, standardMsg))
1127
1128 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001129 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1130 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001131
1132 if d1 != d2:
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001133 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
Michael Foord085dfd32010-06-05 12:17:02 +00001134 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001135 pprint.pformat(d1).splitlines(),
1136 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +00001137 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001138 self.fail(self._formatMessage(msg, standardMsg))
1139
Ezio Melotti0f535012011-04-03 18:02:13 +03001140 def assertDictContainsSubset(self, subset, dictionary, msg=None):
1141 """Checks whether dictionary is a superset of subset."""
1142 warnings.warn('assertDictContainsSubset is deprecated',
1143 DeprecationWarning)
1144 missing = []
1145 mismatched = []
1146 for key, value in subset.items():
1147 if key not in dictionary:
1148 missing.append(key)
1149 elif value != dictionary[key]:
1150 mismatched.append('%s, expected: %s, actual: %s' %
1151 (safe_repr(key), safe_repr(value),
1152 safe_repr(dictionary[key])))
1153
1154 if not (missing or mismatched):
1155 return
1156
1157 standardMsg = ''
1158 if missing:
1159 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1160 missing)
1161 if mismatched:
1162 if standardMsg:
1163 standardMsg += '; '
1164 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1165
1166 self.fail(self._formatMessage(msg, standardMsg))
1167
1168
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001169 def assertCountEqual(self, first, second, msg=None):
1170 """An unordered sequence comparison asserting that the same elements,
1171 regardless of order. If the same element occurs more than once,
1172 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001173
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001174 self.assertEqual(Counter(list(first)),
1175 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001176
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001177 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001178 - [0, 1, 1] and [1, 0, 1] compare equal.
1179 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001180
Michael Foord8442a602010-03-20 16:58:04 +00001181 """
Michael Foorde180d392011-01-28 19:51:48 +00001182 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001183 try:
Michael Foorde180d392011-01-28 19:51:48 +00001184 first = collections.Counter(first_seq)
1185 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001186 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001187 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001188 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001189 else:
Michael Foorde180d392011-01-28 19:51:48 +00001190 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001191 return
Michael Foorde180d392011-01-28 19:51:48 +00001192 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001193
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001194 if differences:
1195 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001196 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001197 diffMsg = '\n'.join(lines)
1198 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1199 msg = self._formatMessage(msg, standardMsg)
1200 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001201
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001202 def assertMultiLineEqual(self, first, second, msg=None):
1203 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001204 self.assertIsInstance(first, str, 'First argument is not a string')
1205 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001206
1207 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001208 # don't use difflib if the strings are too long
1209 if (len(first) > self._diffThreshold or
1210 len(second) > self._diffThreshold):
1211 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001212 firstlines = first.splitlines(keepends=True)
1213 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001214 if len(firstlines) == 1 and first.strip('\r\n') == first:
1215 firstlines = [first + '\n']
1216 secondlines = [second + '\n']
Serhiy Storchaka77622f52013-09-23 23:07:00 +03001217 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
Michael Foordc653ce32010-07-10 13:52:22 +00001218 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001219 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001220 self.fail(self._formatMessage(msg, standardMsg))
1221
1222 def assertLess(self, a, b, msg=None):
1223 """Just like self.assertTrue(a < b), but with a nicer default message."""
1224 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001225 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001226 self.fail(self._formatMessage(msg, standardMsg))
1227
1228 def assertLessEqual(self, a, b, msg=None):
1229 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1230 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001231 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001232 self.fail(self._formatMessage(msg, standardMsg))
1233
1234 def assertGreater(self, a, b, msg=None):
1235 """Just like self.assertTrue(a > b), but with a nicer default message."""
1236 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001237 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001238 self.fail(self._formatMessage(msg, standardMsg))
1239
1240 def assertGreaterEqual(self, a, b, msg=None):
1241 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1242 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001243 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001244 self.fail(self._formatMessage(msg, standardMsg))
1245
1246 def assertIsNone(self, obj, msg=None):
1247 """Same as self.assertTrue(obj is None), with a nicer default message."""
1248 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001249 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001250 self.fail(self._formatMessage(msg, standardMsg))
1251
1252 def assertIsNotNone(self, obj, msg=None):
1253 """Included for symmetry with assertIsNone."""
1254 if obj is None:
1255 standardMsg = 'unexpectedly None'
1256 self.fail(self._formatMessage(msg, standardMsg))
1257
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001258 def assertIsInstance(self, obj, cls, msg=None):
1259 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1260 default message."""
1261 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001262 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001263 self.fail(self._formatMessage(msg, standardMsg))
1264
1265 def assertNotIsInstance(self, obj, cls, msg=None):
1266 """Included for symmetry with assertIsInstance."""
1267 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001268 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001269 self.fail(self._formatMessage(msg, standardMsg))
1270
Ezio Melottied3a7d22010-12-01 02:32:32 +00001271 def assertRaisesRegex(self, expected_exception, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001272 *args, **kwargs):
Ezio Melottied3a7d22010-12-01 02:32:32 +00001273 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001274
1275 Args:
1276 expected_exception: Exception class expected to be raised.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001277 expected_regex: Regex (re.Pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001278 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001279 args: Function to be called and extra positional args.
1280 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001281 msg: Optional message used in case of failure. Can only be used
1282 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001283 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001284 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1285 return context.handle('assertRaisesRegex', args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001286
Ezio Melottied3a7d22010-12-01 02:32:32 +00001287 def assertWarnsRegex(self, expected_warning, expected_regex,
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001288 *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001289 """Asserts that the message in a triggered warning matches a regexp.
1290 Basic functioning is similar to assertWarns() with the addition
1291 that only warnings whose messages also match the regular expression
1292 are considered successful matches.
1293
1294 Args:
1295 expected_warning: Warning class expected to be triggered.
Serhiy Storchaka0b5e61d2017-10-04 20:09:49 +03001296 expected_regex: Regex (re.Pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001297 to be found in error message.
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001298 args: Function to be called and extra positional args.
1299 kwargs: Extra kwargs.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001300 msg: Optional message used in case of failure. Can only be used
1301 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001302 """
Serhiy Storchakadf573d62015-05-16 16:29:50 +03001303 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1304 return context.handle('assertWarnsRegex', args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001305
Ezio Melottied3a7d22010-12-01 02:32:32 +00001306 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001307 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001308 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001309 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001310 expected_regex = re.compile(expected_regex)
1311 if not expected_regex.search(text):
Robert Collinsbe6caca2015-08-20 11:13:09 +12001312 standardMsg = "Regex didn't match: %r not found in %r" % (
1313 expected_regex.pattern, text)
1314 # _formatMessage ensures the longMessage option is respected
1315 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001316 raise self.failureException(msg)
1317
Ezio Melotti8f776302010-12-10 02:32:05 +00001318 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001319 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001320 if isinstance(unexpected_regex, (str, bytes)):
1321 unexpected_regex = re.compile(unexpected_regex)
1322 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001323 if match:
Robert Collinsbe6caca2015-08-20 11:13:09 +12001324 standardMsg = 'Regex matched: %r matches %r in %r' % (
1325 text[match.start() : match.end()],
1326 unexpected_regex.pattern,
1327 text)
1328 # _formatMessage ensures the longMessage option is respected
1329 msg = self._formatMessage(msg, standardMsg)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001330 raise self.failureException(msg)
1331
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001332
Ezio Melottied3a7d22010-12-01 02:32:32 +00001333 def _deprecate(original_func):
1334 def deprecated_func(*args, **kwargs):
1335 warnings.warn(
1336 'Please use {0} instead.'.format(original_func.__name__),
1337 DeprecationWarning, 2)
1338 return original_func(*args, **kwargs)
1339 return deprecated_func
1340
Ezio Melotti361467e2011-04-03 17:37:58 +03001341 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001342 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1343 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1344 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1345 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1346 failUnless = assert_ = _deprecate(assertTrue)
1347 failUnlessRaises = _deprecate(assertRaises)
1348 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001349 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1350 assertRegexpMatches = _deprecate(assertRegex)
Robert Collinsbe6caca2015-08-20 11:13:09 +12001351 assertNotRegexpMatches = _deprecate(assertNotRegex)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001352
1353
1354
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001355class FunctionTestCase(TestCase):
1356 """A test case that wraps a test function.
1357
1358 This is useful for slipping pre-existing test functions into the
1359 unittest framework. Optionally, set-up and tidy-up functions can be
1360 supplied. As with TestCase, the tidy-up ('tearDown') function will
1361 always be called if the set-up ('setUp') function ran successfully.
1362 """
1363
1364 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1365 super(FunctionTestCase, self).__init__()
1366 self._setUpFunc = setUp
1367 self._tearDownFunc = tearDown
1368 self._testFunc = testFunc
1369 self._description = description
1370
1371 def setUp(self):
1372 if self._setUpFunc is not None:
1373 self._setUpFunc()
1374
1375 def tearDown(self):
1376 if self._tearDownFunc is not None:
1377 self._tearDownFunc()
1378
1379 def runTest(self):
1380 self._testFunc()
1381
1382 def id(self):
1383 return self._testFunc.__name__
1384
1385 def __eq__(self, other):
1386 if not isinstance(other, self.__class__):
1387 return NotImplemented
1388
1389 return self._setUpFunc == other._setUpFunc and \
1390 self._tearDownFunc == other._tearDownFunc and \
1391 self._testFunc == other._testFunc and \
1392 self._description == other._description
1393
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001394 def __hash__(self):
1395 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1396 self._testFunc, self._description))
1397
1398 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001399 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001400 self._testFunc.__name__)
1401
1402 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001403 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001404 self._testFunc)
1405
1406 def shortDescription(self):
1407 if self._description is not None:
1408 return self._description
1409 doc = self._testFunc.__doc__
1410 return doc and doc.split("\n")[0].strip() or None
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001411
1412
1413class _SubTest(TestCase):
1414
1415 def __init__(self, test_case, message, params):
1416 super().__init__()
1417 self._message = message
1418 self.test_case = test_case
1419 self.params = params
1420 self.failureException = test_case.failureException
1421
1422 def runTest(self):
1423 raise NotImplementedError("subtests cannot be run directly")
1424
1425 def _subDescription(self):
1426 parts = []
Berker Peksag16ea19f2016-09-21 19:34:15 +03001427 if self._message is not _subtest_msg_sentinel:
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001428 parts.append("[{}]".format(self._message))
1429 if self.params:
1430 params_desc = ', '.join(
1431 "{}={!r}".format(k, v)
Serhiy Storchaka48fbe522017-06-23 21:47:39 +03001432 for (k, v) in self.params.items())
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01001433 parts.append("({})".format(params_desc))
1434 return " ".join(parts) or '(<subtest>)'
1435
1436 def id(self):
1437 return "{} {}".format(self.test_case.id(), self._subDescription())
1438
1439 def shortDescription(self):
1440 """Returns a one-line description of the subtest, or None if no
1441 description has been provided.
1442 """
1443 return self.test_case.shortDescription()
1444
1445 def __str__(self):
1446 return "{} {}".format(self.test_case, self._subDescription())