blob: f56af5574b019370694b15cb5a77ff67f39e4eb1 [file] [log] [blame]
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001"""Test case implementation"""
2
3import sys
4import functools
5import difflib
6import pprint
7import re
8import warnings
Raymond Hettinger6e165b32010-11-27 09:31:37 +00009import collections
Benjamin Petersonbed7d042009-07-19 21:01:52 +000010
Benjamin Peterson847a4112010-03-14 15:04:17 +000011from . import result
Florent Xiclunac53ae582011-11-04 08:25:54 +010012from .util import (strclass, safe_repr, _count_diff_all_purpose,
Raymond Hettinger93e233d2010-12-24 10:02:22 +000013 _count_diff_hashable)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000014
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000015__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000016
Michael Foord9dad32e2010-06-05 13:49:56 +000017
18DIFF_OMITTED = ('\nDiff is %s characters long. '
19 'Set self.maxDiff to None to see it.')
20
Benjamin Petersonbed7d042009-07-19 21:01:52 +000021class SkipTest(Exception):
22 """
23 Raise this exception in a test to skip it.
24
Ezio Melotti265281a2013-03-27 20:11:55 +020025 Usually you can use TestCase.skipTest() or one of the skipping decorators
Benjamin Petersonbed7d042009-07-19 21:01:52 +000026 instead of raising this directly.
27 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000028
29class _ExpectedFailure(Exception):
30 """
31 Raise this when a test is expected to fail.
32
33 This is an implementation detail.
34 """
35
36 def __init__(self, exc_info):
37 super(_ExpectedFailure, self).__init__()
38 self.exc_info = exc_info
39
40class _UnexpectedSuccess(Exception):
41 """
42 The test was supposed to fail, but it didn't!
43 """
Michael Foordb3468f72010-12-19 03:19:47 +000044
45
46class _Outcome(object):
47 def __init__(self):
48 self.success = True
49 self.skipped = None
50 self.unexpectedSuccess = None
51 self.expectedFailure = None
52 self.errors = []
53 self.failures = []
54
Benjamin Petersonbed7d042009-07-19 21:01:52 +000055
56def _id(obj):
57 return obj
58
59def skip(reason):
60 """
61 Unconditionally skip a test.
62 """
63 def decorator(test_item):
Antoine Pitroub05ac862012-04-25 14:56:46 +020064 if not isinstance(test_item, type):
Benjamin Peterson847a4112010-03-14 15:04:17 +000065 @functools.wraps(test_item)
66 def skip_wrapper(*args, **kwargs):
67 raise SkipTest(reason)
68 test_item = skip_wrapper
69
70 test_item.__unittest_skip__ = True
71 test_item.__unittest_skip_why__ = reason
72 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000073 return decorator
74
75def skipIf(condition, reason):
76 """
77 Skip a test if the condition is true.
78 """
79 if condition:
80 return skip(reason)
81 return _id
82
83def skipUnless(condition, reason):
84 """
85 Skip a test unless the condition is true.
86 """
87 if not condition:
88 return skip(reason)
89 return _id
90
91
92def expectedFailure(func):
93 @functools.wraps(func)
94 def wrapper(*args, **kwargs):
95 try:
96 func(*args, **kwargs)
97 except Exception:
98 raise _ExpectedFailure(sys.exc_info())
99 raise _UnexpectedSuccess
100 return wrapper
101
102
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000103class _AssertRaisesBaseContext(object):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000104
105 def __init__(self, expected, test_case, callable_obj=None,
Ezio Melottib4dc2502011-05-06 15:01:41 +0300106 expected_regex=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000107 self.expected = expected
Ezio Melottib4dc2502011-05-06 15:01:41 +0300108 self.test_case = test_case
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000109 if callable_obj is not None:
110 try:
111 self.obj_name = callable_obj.__name__
112 except AttributeError:
113 self.obj_name = str(callable_obj)
114 else:
115 self.obj_name = None
Ezio Melottied3a7d22010-12-01 02:32:32 +0000116 if isinstance(expected_regex, (bytes, str)):
117 expected_regex = re.compile(expected_regex)
118 self.expected_regex = expected_regex
Ezio Melottib4dc2502011-05-06 15:01:41 +0300119 self.msg = None
120
121 def _raiseFailure(self, standardMsg):
122 msg = self.test_case._formatMessage(self.msg, standardMsg)
123 raise self.test_case.failureException(msg)
124
125 def handle(self, name, callable_obj, args, kwargs):
126 """
127 If callable_obj is None, assertRaises/Warns is being used as a
128 context manager, so check for a 'msg' kwarg and return self.
129 If callable_obj is not None, call it passing args and kwargs.
130 """
131 if callable_obj is None:
132 self.msg = kwargs.pop('msg', None)
133 return self
134 with self:
135 callable_obj(*args, **kwargs)
136
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000137
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000138
139class _AssertRaisesContext(_AssertRaisesBaseContext):
140 """A context manager used to implement TestCase.assertRaises* methods."""
141
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000142 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000143 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000144
145 def __exit__(self, exc_type, exc_value, tb):
146 if exc_type is None:
147 try:
148 exc_name = self.expected.__name__
149 except AttributeError:
150 exc_name = str(self.expected)
151 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300152 self._raiseFailure("{} not raised by {}".format(exc_name,
153 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000154 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300155 self._raiseFailure("{} not raised".format(exc_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000156 if not issubclass(exc_type, self.expected):
157 # let unexpected exceptions pass through
158 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000159 # store exception, without traceback, for later retrieval
160 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000161 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000162 return True
163
Ezio Melottied3a7d22010-12-01 02:32:32 +0000164 expected_regex = self.expected_regex
165 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300166 self._raiseFailure('"{}" does not match "{}"'.format(
167 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000168 return True
169
170
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000171class _AssertWarnsContext(_AssertRaisesBaseContext):
172 """A context manager used to implement TestCase.assertWarns* methods."""
173
174 def __enter__(self):
175 # The __warningregistry__'s need to be in a pristine state for tests
176 # to work properly.
177 for v in sys.modules.values():
178 if getattr(v, '__warningregistry__', None):
179 v.__warningregistry__ = {}
180 self.warnings_manager = warnings.catch_warnings(record=True)
181 self.warnings = self.warnings_manager.__enter__()
182 warnings.simplefilter("always", self.expected)
183 return self
184
185 def __exit__(self, exc_type, exc_value, tb):
186 self.warnings_manager.__exit__(exc_type, exc_value, tb)
187 if exc_type is not None:
188 # let unexpected exceptions pass through
189 return
190 try:
191 exc_name = self.expected.__name__
192 except AttributeError:
193 exc_name = str(self.expected)
194 first_matching = None
195 for m in self.warnings:
196 w = m.message
197 if not isinstance(w, self.expected):
198 continue
199 if first_matching is None:
200 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000201 if (self.expected_regex is not None and
202 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000203 continue
204 # store warning for later retrieval
205 self.warning = w
206 self.filename = m.filename
207 self.lineno = m.lineno
208 return
209 # Now we simply try to choose a helpful failure message
210 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300211 self._raiseFailure('"{}" does not match "{}"'.format(
212 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000213 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300214 self._raiseFailure("{} not triggered by {}".format(exc_name,
215 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000216 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300217 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000218
219
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000220class TestCase(object):
221 """A class whose instances are single test cases.
222
223 By default, the test code itself should be placed in a method named
224 'runTest'.
225
226 If the fixture may be used for many test cases, create as
227 many test methods as are needed. When instantiating such a TestCase
228 subclass, specify in the constructor arguments the name of the test method
229 that the instance is to execute.
230
231 Test authors should subclass TestCase for their own tests. Construction
232 and deconstruction of the test's environment ('fixture') can be
233 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
234
235 If it is necessary to override the __init__ method, the base class
236 __init__ method must always be called. It is important that subclasses
237 should not change the signature of their __init__ method, since instances
238 of the classes are instantiated automatically by parts of the framework
239 in order to be run.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000240
Ezio Melotti31797e52013-03-29 03:42:29 +0200241 When subclassing TestCase, you can set these attributes:
242 * failureException: determines which exception will be raised when
243 the instance's assertion methods fail; test methods raising this
244 exception will be deemed to have 'failed' rather than 'errored'.
245 * longMessage: determines whether long messages (including repr of
246 objects used in assert methods) will be printed on failure in *addition*
247 to any explicit message passed.
248 * maxDiff: sets the maximum length of a diff in failure messages
249 by assert methods using difflib. It is looked up as an instance
250 attribute so can be configured by individual tests if required.
251 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000252
253 failureException = AssertionError
254
Michael Foord5074df62010-12-03 00:53:09 +0000255 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000256
Michael Foord085dfd32010-06-05 12:17:02 +0000257 maxDiff = 80*8
258
Ezio Melottiedd117f2011-04-27 10:20:38 +0300259 # If a string is longer than _diffThreshold, use normal comparison instead
260 # of difflib. See #11763.
261 _diffThreshold = 2**16
262
Benjamin Peterson847a4112010-03-14 15:04:17 +0000263 # Attribute used by TestSuite for classSetUp
264
265 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000266
267 def __init__(self, methodName='runTest'):
268 """Create an instance of the class that will use the named test
269 method when executed. Raises a ValueError if the instance does
270 not have a method with the specified name.
271 """
272 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000273 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000274 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000275 try:
276 testMethod = getattr(self, methodName)
277 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000278 if methodName != 'runTest':
279 # we allow instantiation with no explicit method name
280 # but not an *incorrect* or missing method name
281 raise ValueError("no such test method in %s: %s" %
282 (self.__class__, methodName))
283 else:
284 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000285 self._cleanups = []
286
287 # Map types to custom assertEqual functions that will compare
288 # instances of said type in more detail to generate a more useful
289 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500290 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000291 self.addTypeEqualityFunc(dict, 'assertDictEqual')
292 self.addTypeEqualityFunc(list, 'assertListEqual')
293 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
294 self.addTypeEqualityFunc(set, 'assertSetEqual')
295 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
296 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000297
298 def addTypeEqualityFunc(self, typeobj, function):
299 """Add a type specific assertEqual style function to compare a type.
300
301 This method is for use by TestCase subclasses that need to register
302 their own type equality functions to provide nicer error messages.
303
304 Args:
305 typeobj: The data type to call this function on when both values
306 are of the same type in assertEqual().
307 function: The callable taking two arguments and an optional
308 msg= argument that raises self.failureException with a
309 useful error message when the two arguments are not equal.
310 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000311 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000312
313 def addCleanup(self, function, *args, **kwargs):
314 """Add a function, with arguments, to be called when the test is
315 completed. Functions added are called on a LIFO basis and are
316 called after tearDown on test failure or success.
317
318 Cleanup items are called even if setUp fails (unlike tearDown)."""
319 self._cleanups.append((function, args, kwargs))
320
321 def setUp(self):
322 "Hook method for setting up the test fixture before exercising it."
323 pass
324
325 def tearDown(self):
326 "Hook method for deconstructing the test fixture after testing it."
327 pass
328
Benjamin Peterson847a4112010-03-14 15:04:17 +0000329 @classmethod
330 def setUpClass(cls):
331 "Hook method for setting up class fixture before running tests in the class."
332
333 @classmethod
334 def tearDownClass(cls):
335 "Hook method for deconstructing the class fixture after running all tests in the class."
336
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000337 def countTestCases(self):
338 return 1
339
340 def defaultTestResult(self):
341 return result.TestResult()
342
343 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000344 """Returns a one-line description of the test, or None if no
345 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000346
Michael Foord34c94622010-02-10 15:51:42 +0000347 The default implementation of this method returns the first line of
348 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000349 """
Michael Foord34c94622010-02-10 15:51:42 +0000350 doc = self._testMethodDoc
351 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000352
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000353
354 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000355 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000356
357 def __eq__(self, other):
358 if type(self) is not type(other):
359 return NotImplemented
360
361 return self._testMethodName == other._testMethodName
362
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000363 def __hash__(self):
364 return hash((type(self), self._testMethodName))
365
366 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000367 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000368
369 def __repr__(self):
370 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000371 (strclass(self.__class__), self._testMethodName)
372
373 def _addSkip(self, result, reason):
374 addSkip = getattr(result, 'addSkip', None)
375 if addSkip is not None:
376 addSkip(self, reason)
377 else:
378 warnings.warn("TestResult has no addSkip method, skips not reported",
379 RuntimeWarning, 2)
380 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000381
Michael Foordb3468f72010-12-19 03:19:47 +0000382 def _executeTestPart(self, function, outcome, isTest=False):
383 try:
384 function()
385 except KeyboardInterrupt:
386 raise
387 except SkipTest as e:
388 outcome.success = False
389 outcome.skipped = str(e)
390 except _UnexpectedSuccess:
391 exc_info = sys.exc_info()
392 outcome.success = False
393 if isTest:
394 outcome.unexpectedSuccess = exc_info
395 else:
396 outcome.errors.append(exc_info)
397 except _ExpectedFailure:
398 outcome.success = False
399 exc_info = sys.exc_info()
400 if isTest:
401 outcome.expectedFailure = exc_info
402 else:
403 outcome.errors.append(exc_info)
404 except self.failureException:
405 outcome.success = False
406 outcome.failures.append(sys.exc_info())
407 exc_info = sys.exc_info()
408 except:
409 outcome.success = False
410 outcome.errors.append(sys.exc_info())
411
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000412 def run(self, result=None):
413 orig_result = result
414 if result is None:
415 result = self.defaultTestResult()
416 startTestRun = getattr(result, 'startTestRun', None)
417 if startTestRun is not None:
418 startTestRun()
419
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000420 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000421
422 testMethod = getattr(self, self._testMethodName)
423 if (getattr(self.__class__, "__unittest_skip__", False) or
424 getattr(testMethod, "__unittest_skip__", False)):
425 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000426 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000427 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
428 or getattr(testMethod, '__unittest_skip_why__', ''))
429 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000430 finally:
431 result.stopTest(self)
432 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000433 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000434 outcome = _Outcome()
435 self._outcomeForDoCleanups = outcome
436
437 self._executeTestPart(self.setUp, outcome)
438 if outcome.success:
439 self._executeTestPart(testMethod, outcome, isTest=True)
440 self._executeTestPart(self.tearDown, outcome)
441
442 self.doCleanups()
443 if outcome.success:
444 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000445 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000446 if outcome.skipped is not None:
447 self._addSkip(result, outcome.skipped)
448 for exc_info in outcome.errors:
449 result.addError(self, exc_info)
450 for exc_info in outcome.failures:
451 result.addFailure(self, exc_info)
452 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000453 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
454 if addUnexpectedSuccess is not None:
455 addUnexpectedSuccess(self)
456 else:
457 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
458 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000459 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000460
Michael Foordb3468f72010-12-19 03:19:47 +0000461 if outcome.expectedFailure is not None:
462 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
463 if addExpectedFailure is not None:
464 addExpectedFailure(self, outcome.expectedFailure)
465 else:
466 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
467 RuntimeWarning)
468 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400469 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000470 finally:
471 result.stopTest(self)
472 if orig_result is None:
473 stopTestRun = getattr(result, 'stopTestRun', None)
474 if stopTestRun is not None:
475 stopTestRun()
476
477 def doCleanups(self):
478 """Execute all cleanup functions. Normally called for you after
479 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000480 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000481 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000482 function, args, kwargs = self._cleanups.pop()
483 part = lambda: function(*args, **kwargs)
484 self._executeTestPart(part, outcome)
485
486 # return this for backwards compatibility
487 # even though we no longer us it internally
488 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000489
490 def __call__(self, *args, **kwds):
491 return self.run(*args, **kwds)
492
493 def debug(self):
494 """Run the test without collecting errors in a TestResult"""
495 self.setUp()
496 getattr(self, self._testMethodName)()
497 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000498 while self._cleanups:
499 function, args, kwargs = self._cleanups.pop(-1)
500 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000501
502 def skipTest(self, reason):
503 """Skip this test."""
504 raise SkipTest(reason)
505
506 def fail(self, msg=None):
507 """Fail immediately, with the given message."""
508 raise self.failureException(msg)
509
510 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000511 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000512 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000513 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000514 raise self.failureException(msg)
515
516 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000517 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000518 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000519 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000520 raise self.failureException(msg)
521
522 def _formatMessage(self, msg, standardMsg):
523 """Honour the longMessage attribute when generating failure messages.
524 If longMessage is False this means:
525 * Use only an explicit message if it is provided
526 * Otherwise use the standard message for the assert
527
528 If longMessage is True:
529 * Use the standard message
530 * If an explicit message is provided, plus ' : ' and the explicit message
531 """
532 if not self.longMessage:
533 return msg or standardMsg
534 if msg is None:
535 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000536 try:
537 # don't switch to '{}' formatting in Python 2.X
538 # it changes the way unicode input is handled
539 return '%s : %s' % (standardMsg, msg)
540 except UnicodeDecodeError:
541 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000542
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000543 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
Andrew Svetlov737fb892012-12-18 21:14:22 +0200544 """Fail unless an exception of class excClass is raised
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000545 by callableObj when invoked with arguments args and keyword
546 arguments kwargs. If a different type of exception is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200547 raised, it will not be caught, and the test case will be
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000548 deemed to have suffered an error, exactly as for an
549 unexpected exception.
550
551 If called with callableObj omitted or None, will return a
552 context object used like this::
553
Michael Foord1c42b122010-02-05 22:58:21 +0000554 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000555 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000556
Ezio Melottib4dc2502011-05-06 15:01:41 +0300557 An optional keyword argument 'msg' can be provided when assertRaises
558 is used as a context object.
559
Michael Foord1c42b122010-02-05 22:58:21 +0000560 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000561 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000562 exception after the assertion::
563
564 with self.assertRaises(SomeException) as cm:
565 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000566 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000567 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000568 """
569 context = _AssertRaisesContext(excClass, self, callableObj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300570 return context.handle('assertRaises', callableObj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000571
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000572 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
573 """Fail unless a warning of class warnClass is triggered
Ezio Melottib4dc2502011-05-06 15:01:41 +0300574 by callable_obj when invoked with arguments args and keyword
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000575 arguments kwargs. If a different type of warning is
576 triggered, it will not be handled: depending on the other
577 warning filtering rules in effect, it might be silenced, printed
578 out, or raised as an exception.
579
Ezio Melottib4dc2502011-05-06 15:01:41 +0300580 If called with callable_obj omitted or None, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000581 context object used like this::
582
583 with self.assertWarns(SomeWarning):
584 do_something()
585
Ezio Melottib4dc2502011-05-06 15:01:41 +0300586 An optional keyword argument 'msg' can be provided when assertWarns
587 is used as a context object.
588
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000589 The context manager keeps a reference to the first matching
590 warning as the 'warning' attribute; similarly, the 'filename'
591 and 'lineno' attributes give you information about the line
592 of Python code from which the warning was triggered.
593 This allows you to inspect the warning after the assertion::
594
595 with self.assertWarns(SomeWarning) as cm:
596 do_something()
597 the_warning = cm.warning
598 self.assertEqual(the_warning.some_attribute, 147)
599 """
600 context = _AssertWarnsContext(expected_warning, self, callable_obj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300601 return context.handle('assertWarns', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000602
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000603 def _getAssertEqualityFunc(self, first, second):
604 """Get a detailed comparison function for the types of the two args.
605
606 Returns: A callable accepting (first, second, msg=None) that will
607 raise a failure exception if first != second with a useful human
608 readable error message for those types.
609 """
610 #
611 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
612 # and vice versa. I opted for the conservative approach in case
613 # subclasses are not intended to be compared in detail to their super
614 # class instances using a type equality func. This means testing
615 # subtypes won't automagically use the detailed comparison. Callers
616 # should use their type specific assertSpamEqual method to compare
617 # subclasses if the detailed comparison is desired and appropriate.
618 # See the discussion in http://bugs.python.org/issue2578.
619 #
620 if type(first) is type(second):
621 asserter = self._type_equality_funcs.get(type(first))
622 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500623 if isinstance(asserter, str):
624 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000625 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000626
627 return self._baseAssertEqual
628
629 def _baseAssertEqual(self, first, second, msg=None):
630 """The default assertEqual implementation, not type specific."""
631 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000632 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000633 msg = self._formatMessage(msg, standardMsg)
634 raise self.failureException(msg)
635
636 def assertEqual(self, first, second, msg=None):
637 """Fail if the two objects are unequal as determined by the '=='
638 operator.
639 """
640 assertion_func = self._getAssertEqualityFunc(first, second)
641 assertion_func(first, second, msg=msg)
642
643 def assertNotEqual(self, first, second, msg=None):
Ezio Melotti90eea972012-11-08 11:08:39 +0200644 """Fail if the two objects are equal as determined by the '!='
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000645 operator.
646 """
647 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000648 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
649 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000650 raise self.failureException(msg)
651
Michael Foord321d0592010-11-02 13:44:51 +0000652 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000653 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000654 """Fail if the two objects are unequal as determined by their
655 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000656 (default 7) and comparing to zero, or by comparing that the
657 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000658
659 Note that decimal places (from zero) are usually not the same
660 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000661
662 If the two objects compare equal then they will automatically
663 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000664 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000665 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000666 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000667 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000668 if delta is not None and places is not None:
669 raise TypeError("specify delta or places not both")
670
671 if delta is not None:
672 if abs(first - second) <= delta:
673 return
674
675 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
676 safe_repr(second),
677 safe_repr(delta))
678 else:
679 if places is None:
680 places = 7
681
682 if round(abs(second-first), places) == 0:
683 return
684
Benjamin Peterson847a4112010-03-14 15:04:17 +0000685 standardMsg = '%s != %s within %r places' % (safe_repr(first),
686 safe_repr(second),
687 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000688 msg = self._formatMessage(msg, standardMsg)
689 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000690
Michael Foord321d0592010-11-02 13:44:51 +0000691 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000692 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000693 """Fail if the two objects are equal as determined by their
694 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000695 (default 7) and comparing to zero, or by comparing that the
696 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000697
698 Note that decimal places (from zero) are usually not the same
699 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000700
701 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000702 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000703 if delta is not None and places is not None:
704 raise TypeError("specify delta or places not both")
705 if delta is not None:
706 if not (first == second) and abs(first - second) > delta:
707 return
708 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
709 safe_repr(second),
710 safe_repr(delta))
711 else:
712 if places is None:
713 places = 7
714 if not (first == second) and round(abs(second-first), places) != 0:
715 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000716 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000717 safe_repr(second),
718 places)
719
720 msg = self._formatMessage(msg, standardMsg)
721 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000722
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000723
Michael Foord085dfd32010-06-05 12:17:02 +0000724 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000725 """An equality assertion for ordered sequences (like lists and tuples).
726
R. David Murrayad13f222010-01-29 22:17:58 +0000727 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000728 which can be indexed, has a length, and has an equality operator.
729
730 Args:
731 seq1: The first sequence to compare.
732 seq2: The second sequence to compare.
733 seq_type: The expected datatype of the sequences, or None if no
734 datatype should be enforced.
735 msg: Optional message to use on failure instead of a list of
736 differences.
737 """
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400738 if seq_type is not None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000739 seq_type_name = seq_type.__name__
740 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000741 raise self.failureException('First sequence is not a %s: %s'
742 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000743 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000744 raise self.failureException('Second sequence is not a %s: %s'
745 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000746 else:
747 seq_type_name = "sequence"
748
749 differing = None
750 try:
751 len1 = len(seq1)
752 except (TypeError, NotImplementedError):
753 differing = 'First %s has no length. Non-sequence?' % (
754 seq_type_name)
755
756 if differing is None:
757 try:
758 len2 = len(seq2)
759 except (TypeError, NotImplementedError):
760 differing = 'Second %s has no length. Non-sequence?' % (
761 seq_type_name)
762
763 if differing is None:
764 if seq1 == seq2:
765 return
766
Benjamin Peterson847a4112010-03-14 15:04:17 +0000767 seq1_repr = safe_repr(seq1)
768 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000769 if len(seq1_repr) > 30:
770 seq1_repr = seq1_repr[:30] + '...'
771 if len(seq2_repr) > 30:
772 seq2_repr = seq2_repr[:30] + '...'
773 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
774 differing = '%ss differ: %s != %s\n' % elements
775
776 for i in range(min(len1, len2)):
777 try:
778 item1 = seq1[i]
779 except (TypeError, IndexError, NotImplementedError):
780 differing += ('\nUnable to index element %d of first %s\n' %
781 (i, seq_type_name))
782 break
783
784 try:
785 item2 = seq2[i]
786 except (TypeError, IndexError, NotImplementedError):
787 differing += ('\nUnable to index element %d of second %s\n' %
788 (i, seq_type_name))
789 break
790
791 if item1 != item2:
792 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
793 (i, item1, item2))
794 break
795 else:
796 if (len1 == len2 and seq_type is None and
797 type(seq1) != type(seq2)):
798 # The sequences are the same, but have differing types.
799 return
800
801 if len1 > len2:
802 differing += ('\nFirst %s contains %d additional '
803 'elements.\n' % (seq_type_name, len1 - len2))
804 try:
805 differing += ('First extra element %d:\n%s\n' %
806 (len2, seq1[len2]))
807 except (TypeError, IndexError, NotImplementedError):
808 differing += ('Unable to index element %d '
809 'of first %s\n' % (len2, seq_type_name))
810 elif len1 < len2:
811 differing += ('\nSecond %s contains %d additional '
812 'elements.\n' % (seq_type_name, len2 - len1))
813 try:
814 differing += ('First extra element %d:\n%s\n' %
815 (len1, seq2[len1]))
816 except (TypeError, IndexError, NotImplementedError):
817 differing += ('Unable to index element %d '
818 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000819 standardMsg = differing
820 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000821 difflib.ndiff(pprint.pformat(seq1).splitlines(),
822 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000823
824 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000825 msg = self._formatMessage(msg, standardMsg)
826 self.fail(msg)
827
Michael Foord085dfd32010-06-05 12:17:02 +0000828 def _truncateMessage(self, message, diff):
829 max_diff = self.maxDiff
830 if max_diff is None or len(diff) <= max_diff:
831 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000832 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000833
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000834 def assertListEqual(self, list1, list2, msg=None):
835 """A list-specific equality assertion.
836
837 Args:
838 list1: The first list to compare.
839 list2: The second list to compare.
840 msg: Optional message to use on failure instead of a list of
841 differences.
842
843 """
844 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
845
846 def assertTupleEqual(self, tuple1, tuple2, msg=None):
847 """A tuple-specific equality assertion.
848
849 Args:
850 tuple1: The first tuple to compare.
851 tuple2: The second tuple to compare.
852 msg: Optional message to use on failure instead of a list of
853 differences.
854 """
855 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
856
857 def assertSetEqual(self, set1, set2, msg=None):
858 """A set-specific equality assertion.
859
860 Args:
861 set1: The first set to compare.
862 set2: The second set to compare.
863 msg: Optional message to use on failure instead of a list of
864 differences.
865
Michael Foord91c9da32010-03-20 17:21:27 +0000866 assertSetEqual uses ducktyping to support different types of sets, and
867 is optimized for sets specifically (parameters must support a
868 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000869 """
870 try:
871 difference1 = set1.difference(set2)
872 except TypeError as e:
873 self.fail('invalid type when attempting set difference: %s' % e)
874 except AttributeError as e:
875 self.fail('first argument does not support set difference: %s' % e)
876
877 try:
878 difference2 = set2.difference(set1)
879 except TypeError as e:
880 self.fail('invalid type when attempting set difference: %s' % e)
881 except AttributeError as e:
882 self.fail('second argument does not support set difference: %s' % e)
883
884 if not (difference1 or difference2):
885 return
886
887 lines = []
888 if difference1:
889 lines.append('Items in the first set but not the second:')
890 for item in difference1:
891 lines.append(repr(item))
892 if difference2:
893 lines.append('Items in the second set but not the first:')
894 for item in difference2:
895 lines.append(repr(item))
896
897 standardMsg = '\n'.join(lines)
898 self.fail(self._formatMessage(msg, standardMsg))
899
900 def assertIn(self, member, container, msg=None):
901 """Just like self.assertTrue(a in b), but with a nicer default message."""
902 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000903 standardMsg = '%s not found in %s' % (safe_repr(member),
904 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000905 self.fail(self._formatMessage(msg, standardMsg))
906
907 def assertNotIn(self, member, container, msg=None):
908 """Just like self.assertTrue(a not in b), but with a nicer default message."""
909 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000910 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
911 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000912 self.fail(self._formatMessage(msg, standardMsg))
913
914 def assertIs(self, expr1, expr2, msg=None):
915 """Just like self.assertTrue(a is b), but with a nicer default message."""
916 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000917 standardMsg = '%s is not %s' % (safe_repr(expr1),
918 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000919 self.fail(self._formatMessage(msg, standardMsg))
920
921 def assertIsNot(self, expr1, expr2, msg=None):
922 """Just like self.assertTrue(a is not b), but with a nicer default message."""
923 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000924 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000925 self.fail(self._formatMessage(msg, standardMsg))
926
927 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000928 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
929 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000930
931 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000932 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000933 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000934 pprint.pformat(d1).splitlines(),
935 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000936 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000937 self.fail(self._formatMessage(msg, standardMsg))
938
Ezio Melotti0f535012011-04-03 18:02:13 +0300939 def assertDictContainsSubset(self, subset, dictionary, msg=None):
940 """Checks whether dictionary is a superset of subset."""
941 warnings.warn('assertDictContainsSubset is deprecated',
942 DeprecationWarning)
943 missing = []
944 mismatched = []
945 for key, value in subset.items():
946 if key not in dictionary:
947 missing.append(key)
948 elif value != dictionary[key]:
949 mismatched.append('%s, expected: %s, actual: %s' %
950 (safe_repr(key), safe_repr(value),
951 safe_repr(dictionary[key])))
952
953 if not (missing or mismatched):
954 return
955
956 standardMsg = ''
957 if missing:
958 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
959 missing)
960 if mismatched:
961 if standardMsg:
962 standardMsg += '; '
963 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
964
965 self.fail(self._formatMessage(msg, standardMsg))
966
967
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000968 def assertCountEqual(self, first, second, msg=None):
969 """An unordered sequence comparison asserting that the same elements,
970 regardless of order. If the same element occurs more than once,
971 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000972
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000973 self.assertEqual(Counter(list(first)),
974 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000975
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000976 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000977 - [0, 1, 1] and [1, 0, 1] compare equal.
978 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000979
Michael Foord8442a602010-03-20 16:58:04 +0000980 """
Michael Foorde180d392011-01-28 19:51:48 +0000981 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +0000982 try:
Michael Foorde180d392011-01-28 19:51:48 +0000983 first = collections.Counter(first_seq)
984 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000985 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +0000986 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +0000987 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000988 else:
Michael Foorde180d392011-01-28 19:51:48 +0000989 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +0000990 return
Michael Foorde180d392011-01-28 19:51:48 +0000991 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000992
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000993 if differences:
994 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000995 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000996 diffMsg = '\n'.join(lines)
997 standardMsg = self._truncateMessage(standardMsg, diffMsg)
998 msg = self._formatMessage(msg, standardMsg)
999 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001000
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001001 def assertMultiLineEqual(self, first, second, msg=None):
1002 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001003 self.assertIsInstance(first, str, 'First argument is not a string')
1004 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001005
1006 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001007 # don't use difflib if the strings are too long
1008 if (len(first) > self._diffThreshold or
1009 len(second) > self._diffThreshold):
1010 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001011 firstlines = first.splitlines(keepends=True)
1012 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001013 if len(firstlines) == 1 and first.strip('\r\n') == first:
1014 firstlines = [first + '\n']
1015 secondlines = [second + '\n']
1016 standardMsg = '%s != %s' % (safe_repr(first, True),
1017 safe_repr(second, True))
1018 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001019 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001020 self.fail(self._formatMessage(msg, standardMsg))
1021
1022 def assertLess(self, a, b, msg=None):
1023 """Just like self.assertTrue(a < b), but with a nicer default message."""
1024 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001025 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001026 self.fail(self._formatMessage(msg, standardMsg))
1027
1028 def assertLessEqual(self, a, b, msg=None):
1029 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1030 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001031 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001032 self.fail(self._formatMessage(msg, standardMsg))
1033
1034 def assertGreater(self, a, b, msg=None):
1035 """Just like self.assertTrue(a > b), but with a nicer default message."""
1036 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001037 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001038 self.fail(self._formatMessage(msg, standardMsg))
1039
1040 def assertGreaterEqual(self, a, b, msg=None):
1041 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1042 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001043 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001044 self.fail(self._formatMessage(msg, standardMsg))
1045
1046 def assertIsNone(self, obj, msg=None):
1047 """Same as self.assertTrue(obj is None), with a nicer default message."""
1048 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001049 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001050 self.fail(self._formatMessage(msg, standardMsg))
1051
1052 def assertIsNotNone(self, obj, msg=None):
1053 """Included for symmetry with assertIsNone."""
1054 if obj is None:
1055 standardMsg = 'unexpectedly None'
1056 self.fail(self._formatMessage(msg, standardMsg))
1057
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001058 def assertIsInstance(self, obj, cls, msg=None):
1059 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1060 default message."""
1061 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001062 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001063 self.fail(self._formatMessage(msg, standardMsg))
1064
1065 def assertNotIsInstance(self, obj, cls, msg=None):
1066 """Included for symmetry with assertIsInstance."""
1067 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001068 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001069 self.fail(self._formatMessage(msg, standardMsg))
1070
Ezio Melottied3a7d22010-12-01 02:32:32 +00001071 def assertRaisesRegex(self, expected_exception, expected_regex,
1072 callable_obj=None, *args, **kwargs):
1073 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001074
1075 Args:
1076 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001077 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001078 to be found in error message.
1079 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001080 msg: Optional message used in case of failure. Can only be used
1081 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001082 args: Extra args.
1083 kwargs: Extra kwargs.
1084 """
1085 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001086 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001087
1088 return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001089
Ezio Melottied3a7d22010-12-01 02:32:32 +00001090 def assertWarnsRegex(self, expected_warning, expected_regex,
1091 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001092 """Asserts that the message in a triggered warning matches a regexp.
1093 Basic functioning is similar to assertWarns() with the addition
1094 that only warnings whose messages also match the regular expression
1095 are considered successful matches.
1096
1097 Args:
1098 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001099 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001100 to be found in error message.
1101 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001102 msg: Optional message used in case of failure. Can only be used
1103 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001104 args: Extra args.
1105 kwargs: Extra kwargs.
1106 """
1107 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001108 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001109 return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001110
Ezio Melottied3a7d22010-12-01 02:32:32 +00001111 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001112 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001113 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001114 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001115 expected_regex = re.compile(expected_regex)
1116 if not expected_regex.search(text):
1117 msg = msg or "Regex didn't match"
1118 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001119 raise self.failureException(msg)
1120
Ezio Melotti8f776302010-12-10 02:32:05 +00001121 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001122 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001123 if isinstance(unexpected_regex, (str, bytes)):
1124 unexpected_regex = re.compile(unexpected_regex)
1125 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001126 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001127 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001128 msg = '%s: %r matches %r in %r' % (msg,
1129 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001130 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001131 text)
1132 raise self.failureException(msg)
1133
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001134
Ezio Melottied3a7d22010-12-01 02:32:32 +00001135 def _deprecate(original_func):
1136 def deprecated_func(*args, **kwargs):
1137 warnings.warn(
1138 'Please use {0} instead.'.format(original_func.__name__),
1139 DeprecationWarning, 2)
1140 return original_func(*args, **kwargs)
1141 return deprecated_func
1142
Ezio Melotti361467e2011-04-03 17:37:58 +03001143 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001144 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1145 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1146 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1147 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1148 failUnless = assert_ = _deprecate(assertTrue)
1149 failUnlessRaises = _deprecate(assertRaises)
1150 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001151 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1152 assertRegexpMatches = _deprecate(assertRegex)
1153
1154
1155
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001156class FunctionTestCase(TestCase):
1157 """A test case that wraps a test function.
1158
1159 This is useful for slipping pre-existing test functions into the
1160 unittest framework. Optionally, set-up and tidy-up functions can be
1161 supplied. As with TestCase, the tidy-up ('tearDown') function will
1162 always be called if the set-up ('setUp') function ran successfully.
1163 """
1164
1165 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1166 super(FunctionTestCase, self).__init__()
1167 self._setUpFunc = setUp
1168 self._tearDownFunc = tearDown
1169 self._testFunc = testFunc
1170 self._description = description
1171
1172 def setUp(self):
1173 if self._setUpFunc is not None:
1174 self._setUpFunc()
1175
1176 def tearDown(self):
1177 if self._tearDownFunc is not None:
1178 self._tearDownFunc()
1179
1180 def runTest(self):
1181 self._testFunc()
1182
1183 def id(self):
1184 return self._testFunc.__name__
1185
1186 def __eq__(self, other):
1187 if not isinstance(other, self.__class__):
1188 return NotImplemented
1189
1190 return self._setUpFunc == other._setUpFunc and \
1191 self._tearDownFunc == other._tearDownFunc and \
1192 self._testFunc == other._testFunc and \
1193 self._description == other._description
1194
1195 def __ne__(self, other):
1196 return not self == other
1197
1198 def __hash__(self):
1199 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1200 self._testFunc, self._description))
1201
1202 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001203 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001204 self._testFunc.__name__)
1205
1206 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001207 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001208 self._testFunc)
1209
1210 def shortDescription(self):
1211 if self._description is not None:
1212 return self._description
1213 doc = self._testFunc.__doc__
1214 return doc and doc.split("\n")[0].strip() or None