blob: cc5f0c397cd4aecfab45c2d66175a453f9416fae [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
12from .util import (strclass, safe_repr, sorted_list_difference,
Raymond Hettinger93e233d2010-12-24 10:02:22 +000013 unorderable_list_difference, _count_diff_all_purpose,
14 _count_diff_hashable)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000015
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000016__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000017
Michael Foord9dad32e2010-06-05 13:49:56 +000018
19DIFF_OMITTED = ('\nDiff is %s characters long. '
20 'Set self.maxDiff to None to see it.')
21
Benjamin Petersonbed7d042009-07-19 21:01:52 +000022class SkipTest(Exception):
23 """
24 Raise this exception in a test to skip it.
25
26 Usually you can use TestResult.skip() or one of the skipping decorators
27 instead of raising this directly.
28 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000029
30class _ExpectedFailure(Exception):
31 """
32 Raise this when a test is expected to fail.
33
34 This is an implementation detail.
35 """
36
37 def __init__(self, exc_info):
38 super(_ExpectedFailure, self).__init__()
39 self.exc_info = exc_info
40
41class _UnexpectedSuccess(Exception):
42 """
43 The test was supposed to fail, but it didn't!
44 """
Michael Foordb3468f72010-12-19 03:19:47 +000045
46
47class _Outcome(object):
48 def __init__(self):
49 self.success = True
50 self.skipped = None
51 self.unexpectedSuccess = None
52 self.expectedFailure = None
53 self.errors = []
54 self.failures = []
55
Benjamin Petersonbed7d042009-07-19 21:01:52 +000056
57def _id(obj):
58 return obj
59
60def skip(reason):
61 """
62 Unconditionally skip a test.
63 """
64 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000065 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
66 @functools.wraps(test_item)
67 def skip_wrapper(*args, **kwargs):
68 raise SkipTest(reason)
69 test_item = skip_wrapper
70
71 test_item.__unittest_skip__ = True
72 test_item.__unittest_skip_why__ = reason
73 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000074 return decorator
75
76def skipIf(condition, reason):
77 """
78 Skip a test if the condition is true.
79 """
80 if condition:
81 return skip(reason)
82 return _id
83
84def skipUnless(condition, reason):
85 """
86 Skip a test unless the condition is true.
87 """
88 if not condition:
89 return skip(reason)
90 return _id
91
92
93def expectedFailure(func):
94 @functools.wraps(func)
95 def wrapper(*args, **kwargs):
96 try:
97 func(*args, **kwargs)
98 except Exception:
99 raise _ExpectedFailure(sys.exc_info())
100 raise _UnexpectedSuccess
101 return wrapper
102
103
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000104class _AssertRaisesBaseContext(object):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000105
106 def __init__(self, expected, test_case, callable_obj=None,
Ezio Melottib4dc2502011-05-06 15:01:41 +0300107 expected_regex=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000108 self.expected = expected
Ezio Melottib4dc2502011-05-06 15:01:41 +0300109 self.test_case = test_case
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000110 if callable_obj is not None:
111 try:
112 self.obj_name = callable_obj.__name__
113 except AttributeError:
114 self.obj_name = str(callable_obj)
115 else:
116 self.obj_name = None
Ezio Melottied3a7d22010-12-01 02:32:32 +0000117 if isinstance(expected_regex, (bytes, str)):
118 expected_regex = re.compile(expected_regex)
119 self.expected_regex = expected_regex
Ezio Melottib4dc2502011-05-06 15:01:41 +0300120 self.msg = None
121
122 def _raiseFailure(self, standardMsg):
123 msg = self.test_case._formatMessage(self.msg, standardMsg)
124 raise self.test_case.failureException(msg)
125
126 def handle(self, name, callable_obj, args, kwargs):
127 """
128 If callable_obj is None, assertRaises/Warns is being used as a
129 context manager, so check for a 'msg' kwarg and return self.
130 If callable_obj is not None, call it passing args and kwargs.
131 """
132 if callable_obj is None:
133 self.msg = kwargs.pop('msg', None)
134 return self
135 with self:
136 callable_obj(*args, **kwargs)
137
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000139
140class _AssertRaisesContext(_AssertRaisesBaseContext):
141 """A context manager used to implement TestCase.assertRaises* methods."""
142
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000143 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000144 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000145
146 def __exit__(self, exc_type, exc_value, tb):
147 if exc_type is None:
148 try:
149 exc_name = self.expected.__name__
150 except AttributeError:
151 exc_name = str(self.expected)
152 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300153 self._raiseFailure("{} not raised by {}".format(exc_name,
154 self.obj_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000155 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300156 self._raiseFailure("{} not raised".format(exc_name))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000157 if not issubclass(exc_type, self.expected):
158 # let unexpected exceptions pass through
159 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000160 # store exception, without traceback, for later retrieval
161 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000162 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000163 return True
164
Ezio Melottied3a7d22010-12-01 02:32:32 +0000165 expected_regex = self.expected_regex
166 if not expected_regex.search(str(exc_value)):
Ezio Melottib4dc2502011-05-06 15:01:41 +0300167 self._raiseFailure('"{}" does not match "{}"'.format(
168 expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000169 return True
170
171
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000172class _AssertWarnsContext(_AssertRaisesBaseContext):
173 """A context manager used to implement TestCase.assertWarns* methods."""
174
175 def __enter__(self):
176 # The __warningregistry__'s need to be in a pristine state for tests
177 # to work properly.
178 for v in sys.modules.values():
179 if getattr(v, '__warningregistry__', None):
180 v.__warningregistry__ = {}
181 self.warnings_manager = warnings.catch_warnings(record=True)
182 self.warnings = self.warnings_manager.__enter__()
183 warnings.simplefilter("always", self.expected)
184 return self
185
186 def __exit__(self, exc_type, exc_value, tb):
187 self.warnings_manager.__exit__(exc_type, exc_value, tb)
188 if exc_type is not None:
189 # let unexpected exceptions pass through
190 return
191 try:
192 exc_name = self.expected.__name__
193 except AttributeError:
194 exc_name = str(self.expected)
195 first_matching = None
196 for m in self.warnings:
197 w = m.message
198 if not isinstance(w, self.expected):
199 continue
200 if first_matching is None:
201 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000202 if (self.expected_regex is not None and
203 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000204 continue
205 # store warning for later retrieval
206 self.warning = w
207 self.filename = m.filename
208 self.lineno = m.lineno
209 return
210 # Now we simply try to choose a helpful failure message
211 if first_matching is not None:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300212 self._raiseFailure('"{}" does not match "{}"'.format(
213 self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000214 if self.obj_name:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300215 self._raiseFailure("{} not triggered by {}".format(exc_name,
216 self.obj_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000217 else:
Ezio Melottib4dc2502011-05-06 15:01:41 +0300218 self._raiseFailure("{} not triggered".format(exc_name))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000219
220
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000221class TestCase(object):
222 """A class whose instances are single test cases.
223
224 By default, the test code itself should be placed in a method named
225 'runTest'.
226
227 If the fixture may be used for many test cases, create as
228 many test methods as are needed. When instantiating such a TestCase
229 subclass, specify in the constructor arguments the name of the test method
230 that the instance is to execute.
231
232 Test authors should subclass TestCase for their own tests. Construction
233 and deconstruction of the test's environment ('fixture') can be
234 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
235
236 If it is necessary to override the __init__ method, the base class
237 __init__ method must always be called. It is important that subclasses
238 should not change the signature of their __init__ method, since instances
239 of the classes are instantiated automatically by parts of the framework
240 in order to be run.
241 """
242
243 # This attribute determines which exception will be raised when
244 # the instance's assertion methods fail; test methods raising this
245 # exception will be deemed to have 'failed' rather than 'errored'
246
247 failureException = AssertionError
248
249 # This attribute determines whether long messages (including repr of
250 # objects used in assert methods) will be printed on failure in *addition*
251 # to any explicit message passed.
252
Michael Foord5074df62010-12-03 00:53:09 +0000253 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000254
Michael Foordc41d1412010-06-10 16:17:07 +0000255 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000256 # by assert methods using difflib. It is looked up as an instance attribute
257 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000258
Michael Foord085dfd32010-06-05 12:17:02 +0000259 maxDiff = 80*8
260
Ezio Melottiedd117f2011-04-27 10:20:38 +0300261 # If a string is longer than _diffThreshold, use normal comparison instead
262 # of difflib. See #11763.
263 _diffThreshold = 2**16
264
Benjamin Peterson847a4112010-03-14 15:04:17 +0000265 # Attribute used by TestSuite for classSetUp
266
267 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000268
269 def __init__(self, methodName='runTest'):
270 """Create an instance of the class that will use the named test
271 method when executed. Raises a ValueError if the instance does
272 not have a method with the specified name.
273 """
274 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000275 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000276 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000277 try:
278 testMethod = getattr(self, methodName)
279 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000280 if methodName != 'runTest':
281 # we allow instantiation with no explicit method name
282 # but not an *incorrect* or missing method name
283 raise ValueError("no such test method in %s: %s" %
284 (self.__class__, methodName))
285 else:
286 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000287 self._cleanups = []
288
289 # Map types to custom assertEqual functions that will compare
290 # instances of said type in more detail to generate a more useful
291 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500292 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000293 self.addTypeEqualityFunc(dict, 'assertDictEqual')
294 self.addTypeEqualityFunc(list, 'assertListEqual')
295 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
296 self.addTypeEqualityFunc(set, 'assertSetEqual')
297 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
298 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000299
300 def addTypeEqualityFunc(self, typeobj, function):
301 """Add a type specific assertEqual style function to compare a type.
302
303 This method is for use by TestCase subclasses that need to register
304 their own type equality functions to provide nicer error messages.
305
306 Args:
307 typeobj: The data type to call this function on when both values
308 are of the same type in assertEqual().
309 function: The callable taking two arguments and an optional
310 msg= argument that raises self.failureException with a
311 useful error message when the two arguments are not equal.
312 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000313 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000314
315 def addCleanup(self, function, *args, **kwargs):
316 """Add a function, with arguments, to be called when the test is
317 completed. Functions added are called on a LIFO basis and are
318 called after tearDown on test failure or success.
319
320 Cleanup items are called even if setUp fails (unlike tearDown)."""
321 self._cleanups.append((function, args, kwargs))
322
323 def setUp(self):
324 "Hook method for setting up the test fixture before exercising it."
325 pass
326
327 def tearDown(self):
328 "Hook method for deconstructing the test fixture after testing it."
329 pass
330
Benjamin Peterson847a4112010-03-14 15:04:17 +0000331 @classmethod
332 def setUpClass(cls):
333 "Hook method for setting up class fixture before running tests in the class."
334
335 @classmethod
336 def tearDownClass(cls):
337 "Hook method for deconstructing the class fixture after running all tests in the class."
338
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000339 def countTestCases(self):
340 return 1
341
342 def defaultTestResult(self):
343 return result.TestResult()
344
345 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000346 """Returns a one-line description of the test, or None if no
347 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000348
Michael Foord34c94622010-02-10 15:51:42 +0000349 The default implementation of this method returns the first line of
350 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000351 """
Michael Foord34c94622010-02-10 15:51:42 +0000352 doc = self._testMethodDoc
353 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000354
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000355
356 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000357 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000358
359 def __eq__(self, other):
360 if type(self) is not type(other):
361 return NotImplemented
362
363 return self._testMethodName == other._testMethodName
364
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000365 def __hash__(self):
366 return hash((type(self), self._testMethodName))
367
368 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000369 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000370
371 def __repr__(self):
372 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000373 (strclass(self.__class__), self._testMethodName)
374
375 def _addSkip(self, result, reason):
376 addSkip = getattr(result, 'addSkip', None)
377 if addSkip is not None:
378 addSkip(self, reason)
379 else:
380 warnings.warn("TestResult has no addSkip method, skips not reported",
381 RuntimeWarning, 2)
382 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000383
Michael Foordb3468f72010-12-19 03:19:47 +0000384 def _executeTestPart(self, function, outcome, isTest=False):
385 try:
386 function()
387 except KeyboardInterrupt:
388 raise
389 except SkipTest as e:
390 outcome.success = False
391 outcome.skipped = str(e)
392 except _UnexpectedSuccess:
393 exc_info = sys.exc_info()
394 outcome.success = False
395 if isTest:
396 outcome.unexpectedSuccess = exc_info
397 else:
398 outcome.errors.append(exc_info)
399 except _ExpectedFailure:
400 outcome.success = False
401 exc_info = sys.exc_info()
402 if isTest:
403 outcome.expectedFailure = exc_info
404 else:
405 outcome.errors.append(exc_info)
406 except self.failureException:
407 outcome.success = False
408 outcome.failures.append(sys.exc_info())
409 exc_info = sys.exc_info()
410 except:
411 outcome.success = False
412 outcome.errors.append(sys.exc_info())
413
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000414 def run(self, result=None):
415 orig_result = result
416 if result is None:
417 result = self.defaultTestResult()
418 startTestRun = getattr(result, 'startTestRun', None)
419 if startTestRun is not None:
420 startTestRun()
421
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000422 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000423
424 testMethod = getattr(self, self._testMethodName)
425 if (getattr(self.__class__, "__unittest_skip__", False) or
426 getattr(testMethod, "__unittest_skip__", False)):
427 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000428 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000429 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
430 or getattr(testMethod, '__unittest_skip_why__', ''))
431 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000432 finally:
433 result.stopTest(self)
434 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000435 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000436 outcome = _Outcome()
437 self._outcomeForDoCleanups = outcome
438
439 self._executeTestPart(self.setUp, outcome)
440 if outcome.success:
441 self._executeTestPart(testMethod, outcome, isTest=True)
442 self._executeTestPart(self.tearDown, outcome)
443
444 self.doCleanups()
445 if outcome.success:
446 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000447 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000448 if outcome.skipped is not None:
449 self._addSkip(result, outcome.skipped)
450 for exc_info in outcome.errors:
451 result.addError(self, exc_info)
452 for exc_info in outcome.failures:
453 result.addFailure(self, exc_info)
454 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000455 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
456 if addUnexpectedSuccess is not None:
457 addUnexpectedSuccess(self)
458 else:
459 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
460 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000461 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000462
Michael Foordb3468f72010-12-19 03:19:47 +0000463 if outcome.expectedFailure is not None:
464 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
465 if addExpectedFailure is not None:
466 addExpectedFailure(self, outcome.expectedFailure)
467 else:
468 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
469 RuntimeWarning)
470 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400471 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000472 finally:
473 result.stopTest(self)
474 if orig_result is None:
475 stopTestRun = getattr(result, 'stopTestRun', None)
476 if stopTestRun is not None:
477 stopTestRun()
478
479 def doCleanups(self):
480 """Execute all cleanup functions. Normally called for you after
481 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000482 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000483 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000484 function, args, kwargs = self._cleanups.pop()
485 part = lambda: function(*args, **kwargs)
486 self._executeTestPart(part, outcome)
487
488 # return this for backwards compatibility
489 # even though we no longer us it internally
490 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000491
492 def __call__(self, *args, **kwds):
493 return self.run(*args, **kwds)
494
495 def debug(self):
496 """Run the test without collecting errors in a TestResult"""
497 self.setUp()
498 getattr(self, self._testMethodName)()
499 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000500 while self._cleanups:
501 function, args, kwargs = self._cleanups.pop(-1)
502 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000503
504 def skipTest(self, reason):
505 """Skip this test."""
506 raise SkipTest(reason)
507
508 def fail(self, msg=None):
509 """Fail immediately, with the given message."""
510 raise self.failureException(msg)
511
512 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000513 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000514 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000515 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000516 raise self.failureException(msg)
517
518 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000519 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000520 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000521 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000522 raise self.failureException(msg)
523
524 def _formatMessage(self, msg, standardMsg):
525 """Honour the longMessage attribute when generating failure messages.
526 If longMessage is False this means:
527 * Use only an explicit message if it is provided
528 * Otherwise use the standard message for the assert
529
530 If longMessage is True:
531 * Use the standard message
532 * If an explicit message is provided, plus ' : ' and the explicit message
533 """
534 if not self.longMessage:
535 return msg or standardMsg
536 if msg is None:
537 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000538 try:
539 # don't switch to '{}' formatting in Python 2.X
540 # it changes the way unicode input is handled
541 return '%s : %s' % (standardMsg, msg)
542 except UnicodeDecodeError:
543 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000544
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000545 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
546 """Fail unless an exception of class excClass is thrown
547 by callableObj when invoked with arguments args and keyword
548 arguments kwargs. If a different type of exception is
549 thrown, it will not be caught, and the test case will be
550 deemed to have suffered an error, exactly as for an
551 unexpected exception.
552
553 If called with callableObj omitted or None, will return a
554 context object used like this::
555
Michael Foord1c42b122010-02-05 22:58:21 +0000556 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000557 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000558
Ezio Melottib4dc2502011-05-06 15:01:41 +0300559 An optional keyword argument 'msg' can be provided when assertRaises
560 is used as a context object.
561
Michael Foord1c42b122010-02-05 22:58:21 +0000562 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000563 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000564 exception after the assertion::
565
566 with self.assertRaises(SomeException) as cm:
567 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000568 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000569 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000570 """
571 context = _AssertRaisesContext(excClass, self, callableObj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300572 return context.handle('assertRaises', callableObj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000573
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000574 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
575 """Fail unless a warning of class warnClass is triggered
Ezio Melottib4dc2502011-05-06 15:01:41 +0300576 by callable_obj when invoked with arguments args and keyword
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000577 arguments kwargs. If a different type of warning is
578 triggered, it will not be handled: depending on the other
579 warning filtering rules in effect, it might be silenced, printed
580 out, or raised as an exception.
581
Ezio Melottib4dc2502011-05-06 15:01:41 +0300582 If called with callable_obj omitted or None, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000583 context object used like this::
584
585 with self.assertWarns(SomeWarning):
586 do_something()
587
Ezio Melottib4dc2502011-05-06 15:01:41 +0300588 An optional keyword argument 'msg' can be provided when assertWarns
589 is used as a context object.
590
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000591 The context manager keeps a reference to the first matching
592 warning as the 'warning' attribute; similarly, the 'filename'
593 and 'lineno' attributes give you information about the line
594 of Python code from which the warning was triggered.
595 This allows you to inspect the warning after the assertion::
596
597 with self.assertWarns(SomeWarning) as cm:
598 do_something()
599 the_warning = cm.warning
600 self.assertEqual(the_warning.some_attribute, 147)
601 """
602 context = _AssertWarnsContext(expected_warning, self, callable_obj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300603 return context.handle('assertWarns', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000604
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000605 def _getAssertEqualityFunc(self, first, second):
606 """Get a detailed comparison function for the types of the two args.
607
608 Returns: A callable accepting (first, second, msg=None) that will
609 raise a failure exception if first != second with a useful human
610 readable error message for those types.
611 """
612 #
613 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
614 # and vice versa. I opted for the conservative approach in case
615 # subclasses are not intended to be compared in detail to their super
616 # class instances using a type equality func. This means testing
617 # subtypes won't automagically use the detailed comparison. Callers
618 # should use their type specific assertSpamEqual method to compare
619 # subclasses if the detailed comparison is desired and appropriate.
620 # See the discussion in http://bugs.python.org/issue2578.
621 #
622 if type(first) is type(second):
623 asserter = self._type_equality_funcs.get(type(first))
624 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500625 if isinstance(asserter, str):
626 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000627 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000628
629 return self._baseAssertEqual
630
631 def _baseAssertEqual(self, first, second, msg=None):
632 """The default assertEqual implementation, not type specific."""
633 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000634 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000635 msg = self._formatMessage(msg, standardMsg)
636 raise self.failureException(msg)
637
638 def assertEqual(self, first, second, msg=None):
639 """Fail if the two objects are unequal as determined by the '=='
640 operator.
641 """
642 assertion_func = self._getAssertEqualityFunc(first, second)
643 assertion_func(first, second, msg=msg)
644
645 def assertNotEqual(self, first, second, msg=None):
646 """Fail if the two objects are equal as determined by the '=='
647 operator.
648 """
649 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000650 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
651 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000652 raise self.failureException(msg)
653
Michael Foord321d0592010-11-02 13:44:51 +0000654 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000655 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656 """Fail if the two objects are unequal as determined by their
657 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000658 (default 7) and comparing to zero, or by comparing that the
659 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000660
661 Note that decimal places (from zero) are usually not the same
662 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000663
664 If the two objects compare equal then they will automatically
665 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000666 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000667 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000668 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000669 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000670 if delta is not None and places is not None:
671 raise TypeError("specify delta or places not both")
672
673 if delta is not None:
674 if abs(first - second) <= delta:
675 return
676
677 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
678 safe_repr(second),
679 safe_repr(delta))
680 else:
681 if places is None:
682 places = 7
683
684 if round(abs(second-first), places) == 0:
685 return
686
Benjamin Peterson847a4112010-03-14 15:04:17 +0000687 standardMsg = '%s != %s within %r places' % (safe_repr(first),
688 safe_repr(second),
689 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000690 msg = self._formatMessage(msg, standardMsg)
691 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000692
Michael Foord321d0592010-11-02 13:44:51 +0000693 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000694 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000695 """Fail if the two objects are equal as determined by their
696 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000697 (default 7) and comparing to zero, or by comparing that the
698 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699
700 Note that decimal places (from zero) are usually not the same
701 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000702
703 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000704 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000705 if delta is not None and places is not None:
706 raise TypeError("specify delta or places not both")
707 if delta is not None:
708 if not (first == second) and abs(first - second) > delta:
709 return
710 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
711 safe_repr(second),
712 safe_repr(delta))
713 else:
714 if places is None:
715 places = 7
716 if not (first == second) and round(abs(second-first), places) != 0:
717 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000718 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000719 safe_repr(second),
720 places)
721
722 msg = self._formatMessage(msg, standardMsg)
723 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000724
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000725
Michael Foord085dfd32010-06-05 12:17:02 +0000726 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000727 """An equality assertion for ordered sequences (like lists and tuples).
728
R. David Murrayad13f222010-01-29 22:17:58 +0000729 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000730 which can be indexed, has a length, and has an equality operator.
731
732 Args:
733 seq1: The first sequence to compare.
734 seq2: The second sequence to compare.
735 seq_type: The expected datatype of the sequences, or None if no
736 datatype should be enforced.
737 msg: Optional message to use on failure instead of a list of
738 differences.
739 """
740 if seq_type != None:
741 seq_type_name = seq_type.__name__
742 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000743 raise self.failureException('First sequence is not a %s: %s'
744 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000745 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000746 raise self.failureException('Second sequence is not a %s: %s'
747 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000748 else:
749 seq_type_name = "sequence"
750
751 differing = None
752 try:
753 len1 = len(seq1)
754 except (TypeError, NotImplementedError):
755 differing = 'First %s has no length. Non-sequence?' % (
756 seq_type_name)
757
758 if differing is None:
759 try:
760 len2 = len(seq2)
761 except (TypeError, NotImplementedError):
762 differing = 'Second %s has no length. Non-sequence?' % (
763 seq_type_name)
764
765 if differing is None:
766 if seq1 == seq2:
767 return
768
Benjamin Peterson847a4112010-03-14 15:04:17 +0000769 seq1_repr = safe_repr(seq1)
770 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000771 if len(seq1_repr) > 30:
772 seq1_repr = seq1_repr[:30] + '...'
773 if len(seq2_repr) > 30:
774 seq2_repr = seq2_repr[:30] + '...'
775 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
776 differing = '%ss differ: %s != %s\n' % elements
777
778 for i in range(min(len1, len2)):
779 try:
780 item1 = seq1[i]
781 except (TypeError, IndexError, NotImplementedError):
782 differing += ('\nUnable to index element %d of first %s\n' %
783 (i, seq_type_name))
784 break
785
786 try:
787 item2 = seq2[i]
788 except (TypeError, IndexError, NotImplementedError):
789 differing += ('\nUnable to index element %d of second %s\n' %
790 (i, seq_type_name))
791 break
792
793 if item1 != item2:
794 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
795 (i, item1, item2))
796 break
797 else:
798 if (len1 == len2 and seq_type is None and
799 type(seq1) != type(seq2)):
800 # The sequences are the same, but have differing types.
801 return
802
803 if len1 > len2:
804 differing += ('\nFirst %s contains %d additional '
805 'elements.\n' % (seq_type_name, len1 - len2))
806 try:
807 differing += ('First extra element %d:\n%s\n' %
808 (len2, seq1[len2]))
809 except (TypeError, IndexError, NotImplementedError):
810 differing += ('Unable to index element %d '
811 'of first %s\n' % (len2, seq_type_name))
812 elif len1 < len2:
813 differing += ('\nSecond %s contains %d additional '
814 'elements.\n' % (seq_type_name, len2 - len1))
815 try:
816 differing += ('First extra element %d:\n%s\n' %
817 (len1, seq2[len1]))
818 except (TypeError, IndexError, NotImplementedError):
819 differing += ('Unable to index element %d '
820 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000821 standardMsg = differing
822 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000823 difflib.ndiff(pprint.pformat(seq1).splitlines(),
824 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000825
826 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000827 msg = self._formatMessage(msg, standardMsg)
828 self.fail(msg)
829
Michael Foord085dfd32010-06-05 12:17:02 +0000830 def _truncateMessage(self, message, diff):
831 max_diff = self.maxDiff
832 if max_diff is None or len(diff) <= max_diff:
833 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000834 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000835
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000836 def assertListEqual(self, list1, list2, msg=None):
837 """A list-specific equality assertion.
838
839 Args:
840 list1: The first list to compare.
841 list2: The second list to compare.
842 msg: Optional message to use on failure instead of a list of
843 differences.
844
845 """
846 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
847
848 def assertTupleEqual(self, tuple1, tuple2, msg=None):
849 """A tuple-specific equality assertion.
850
851 Args:
852 tuple1: The first tuple to compare.
853 tuple2: The second tuple to compare.
854 msg: Optional message to use on failure instead of a list of
855 differences.
856 """
857 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
858
859 def assertSetEqual(self, set1, set2, msg=None):
860 """A set-specific equality assertion.
861
862 Args:
863 set1: The first set to compare.
864 set2: The second set to compare.
865 msg: Optional message to use on failure instead of a list of
866 differences.
867
Michael Foord91c9da32010-03-20 17:21:27 +0000868 assertSetEqual uses ducktyping to support different types of sets, and
869 is optimized for sets specifically (parameters must support a
870 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000871 """
872 try:
873 difference1 = set1.difference(set2)
874 except TypeError as e:
875 self.fail('invalid type when attempting set difference: %s' % e)
876 except AttributeError as e:
877 self.fail('first argument does not support set difference: %s' % e)
878
879 try:
880 difference2 = set2.difference(set1)
881 except TypeError as e:
882 self.fail('invalid type when attempting set difference: %s' % e)
883 except AttributeError as e:
884 self.fail('second argument does not support set difference: %s' % e)
885
886 if not (difference1 or difference2):
887 return
888
889 lines = []
890 if difference1:
891 lines.append('Items in the first set but not the second:')
892 for item in difference1:
893 lines.append(repr(item))
894 if difference2:
895 lines.append('Items in the second set but not the first:')
896 for item in difference2:
897 lines.append(repr(item))
898
899 standardMsg = '\n'.join(lines)
900 self.fail(self._formatMessage(msg, standardMsg))
901
902 def assertIn(self, member, container, msg=None):
903 """Just like self.assertTrue(a in b), but with a nicer default message."""
904 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000905 standardMsg = '%s not found in %s' % (safe_repr(member),
906 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000907 self.fail(self._formatMessage(msg, standardMsg))
908
909 def assertNotIn(self, member, container, msg=None):
910 """Just like self.assertTrue(a not in b), but with a nicer default message."""
911 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000912 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
913 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000914 self.fail(self._formatMessage(msg, standardMsg))
915
916 def assertIs(self, expr1, expr2, msg=None):
917 """Just like self.assertTrue(a is b), but with a nicer default message."""
918 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000919 standardMsg = '%s is not %s' % (safe_repr(expr1),
920 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000921 self.fail(self._formatMessage(msg, standardMsg))
922
923 def assertIsNot(self, expr1, expr2, msg=None):
924 """Just like self.assertTrue(a is not b), but with a nicer default message."""
925 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000926 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000927 self.fail(self._formatMessage(msg, standardMsg))
928
929 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000930 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
931 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000932
933 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000934 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000935 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000936 pprint.pformat(d1).splitlines(),
937 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000938 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000939 self.fail(self._formatMessage(msg, standardMsg))
940
Ezio Melotti0f535012011-04-03 18:02:13 +0300941 def assertDictContainsSubset(self, subset, dictionary, msg=None):
942 """Checks whether dictionary is a superset of subset."""
943 warnings.warn('assertDictContainsSubset is deprecated',
944 DeprecationWarning)
945 missing = []
946 mismatched = []
947 for key, value in subset.items():
948 if key not in dictionary:
949 missing.append(key)
950 elif value != dictionary[key]:
951 mismatched.append('%s, expected: %s, actual: %s' %
952 (safe_repr(key), safe_repr(value),
953 safe_repr(dictionary[key])))
954
955 if not (missing or mismatched):
956 return
957
958 standardMsg = ''
959 if missing:
960 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
961 missing)
962 if mismatched:
963 if standardMsg:
964 standardMsg += '; '
965 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
966
967 self.fail(self._formatMessage(msg, standardMsg))
968
969
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000970 def assertCountEqual(self, first, second, msg=None):
971 """An unordered sequence comparison asserting that the same elements,
972 regardless of order. If the same element occurs more than once,
973 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000974
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000975 self.assertEqual(Counter(list(first)),
976 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000977
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000978 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000979 - [0, 1, 1] and [1, 0, 1] compare equal.
980 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000981
Michael Foord8442a602010-03-20 16:58:04 +0000982 """
Michael Foorde180d392011-01-28 19:51:48 +0000983 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +0000984 try:
Michael Foorde180d392011-01-28 19:51:48 +0000985 first = collections.Counter(first_seq)
986 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000987 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +0000988 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +0000989 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000990 else:
Michael Foorde180d392011-01-28 19:51:48 +0000991 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +0000992 return
Michael Foorde180d392011-01-28 19:51:48 +0000993 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000994
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000995 if differences:
996 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000997 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000998 diffMsg = '\n'.join(lines)
999 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1000 msg = self._formatMessage(msg, standardMsg)
1001 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001002
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001003 def assertMultiLineEqual(self, first, second, msg=None):
1004 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001005 self.assertIsInstance(first, str, 'First argument is not a string')
1006 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001007
1008 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001009 # don't use difflib if the strings are too long
1010 if (len(first) > self._diffThreshold or
1011 len(second) > self._diffThreshold):
1012 self._baseAssertEqual(first, second, msg)
Ezio Melottid8b509b2011-09-28 17:37:55 +03001013 firstlines = first.splitlines(keepends=True)
1014 secondlines = second.splitlines(keepends=True)
Michael Foordc653ce32010-07-10 13:52:22 +00001015 if len(firstlines) == 1 and first.strip('\r\n') == first:
1016 firstlines = [first + '\n']
1017 secondlines = [second + '\n']
1018 standardMsg = '%s != %s' % (safe_repr(first, True),
1019 safe_repr(second, True))
1020 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001021 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001022 self.fail(self._formatMessage(msg, standardMsg))
1023
1024 def assertLess(self, a, b, msg=None):
1025 """Just like self.assertTrue(a < b), but with a nicer default message."""
1026 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001027 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001028 self.fail(self._formatMessage(msg, standardMsg))
1029
1030 def assertLessEqual(self, a, b, msg=None):
1031 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1032 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001033 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001034 self.fail(self._formatMessage(msg, standardMsg))
1035
1036 def assertGreater(self, a, b, msg=None):
1037 """Just like self.assertTrue(a > b), but with a nicer default message."""
1038 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001039 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001040 self.fail(self._formatMessage(msg, standardMsg))
1041
1042 def assertGreaterEqual(self, a, b, msg=None):
1043 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1044 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001045 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001046 self.fail(self._formatMessage(msg, standardMsg))
1047
1048 def assertIsNone(self, obj, msg=None):
1049 """Same as self.assertTrue(obj is None), with a nicer default message."""
1050 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001051 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001052 self.fail(self._formatMessage(msg, standardMsg))
1053
1054 def assertIsNotNone(self, obj, msg=None):
1055 """Included for symmetry with assertIsNone."""
1056 if obj is None:
1057 standardMsg = 'unexpectedly None'
1058 self.fail(self._formatMessage(msg, standardMsg))
1059
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001060 def assertIsInstance(self, obj, cls, msg=None):
1061 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1062 default message."""
1063 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001064 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001065 self.fail(self._formatMessage(msg, standardMsg))
1066
1067 def assertNotIsInstance(self, obj, cls, msg=None):
1068 """Included for symmetry with assertIsInstance."""
1069 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001070 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001071 self.fail(self._formatMessage(msg, standardMsg))
1072
Ezio Melottied3a7d22010-12-01 02:32:32 +00001073 def assertRaisesRegex(self, expected_exception, expected_regex,
1074 callable_obj=None, *args, **kwargs):
1075 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001076
1077 Args:
1078 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001079 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001080 to be found in error message.
1081 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001082 msg: Optional message used in case of failure. Can only be used
1083 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001084 args: Extra args.
1085 kwargs: Extra kwargs.
1086 """
1087 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001088 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001089
1090 return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001091
Ezio Melottied3a7d22010-12-01 02:32:32 +00001092 def assertWarnsRegex(self, expected_warning, expected_regex,
1093 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001094 """Asserts that the message in a triggered warning matches a regexp.
1095 Basic functioning is similar to assertWarns() with the addition
1096 that only warnings whose messages also match the regular expression
1097 are considered successful matches.
1098
1099 Args:
1100 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001101 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001102 to be found in error message.
1103 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001104 msg: Optional message used in case of failure. Can only be used
1105 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001106 args: Extra args.
1107 kwargs: Extra kwargs.
1108 """
1109 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001110 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001111 return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001112
Ezio Melottied3a7d22010-12-01 02:32:32 +00001113 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001114 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001115 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001116 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001117 expected_regex = re.compile(expected_regex)
1118 if not expected_regex.search(text):
1119 msg = msg or "Regex didn't match"
1120 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001121 raise self.failureException(msg)
1122
Ezio Melotti8f776302010-12-10 02:32:05 +00001123 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001124 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001125 if isinstance(unexpected_regex, (str, bytes)):
1126 unexpected_regex = re.compile(unexpected_regex)
1127 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001128 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001129 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001130 msg = '%s: %r matches %r in %r' % (msg,
1131 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001132 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001133 text)
1134 raise self.failureException(msg)
1135
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001136
Ezio Melottied3a7d22010-12-01 02:32:32 +00001137 def _deprecate(original_func):
1138 def deprecated_func(*args, **kwargs):
1139 warnings.warn(
1140 'Please use {0} instead.'.format(original_func.__name__),
1141 DeprecationWarning, 2)
1142 return original_func(*args, **kwargs)
1143 return deprecated_func
1144
Ezio Melotti361467e2011-04-03 17:37:58 +03001145 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001146 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1147 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1148 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1149 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1150 failUnless = assert_ = _deprecate(assertTrue)
1151 failUnlessRaises = _deprecate(assertRaises)
1152 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001153 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1154 assertRegexpMatches = _deprecate(assertRegex)
1155
1156
1157
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001158class FunctionTestCase(TestCase):
1159 """A test case that wraps a test function.
1160
1161 This is useful for slipping pre-existing test functions into the
1162 unittest framework. Optionally, set-up and tidy-up functions can be
1163 supplied. As with TestCase, the tidy-up ('tearDown') function will
1164 always be called if the set-up ('setUp') function ran successfully.
1165 """
1166
1167 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1168 super(FunctionTestCase, self).__init__()
1169 self._setUpFunc = setUp
1170 self._tearDownFunc = tearDown
1171 self._testFunc = testFunc
1172 self._description = description
1173
1174 def setUp(self):
1175 if self._setUpFunc is not None:
1176 self._setUpFunc()
1177
1178 def tearDown(self):
1179 if self._tearDownFunc is not None:
1180 self._tearDownFunc()
1181
1182 def runTest(self):
1183 self._testFunc()
1184
1185 def id(self):
1186 return self._testFunc.__name__
1187
1188 def __eq__(self, other):
1189 if not isinstance(other, self.__class__):
1190 return NotImplemented
1191
1192 return self._setUpFunc == other._setUpFunc and \
1193 self._tearDownFunc == other._tearDownFunc and \
1194 self._testFunc == other._testFunc and \
1195 self._description == other._description
1196
1197 def __ne__(self, other):
1198 return not self == other
1199
1200 def __hash__(self):
1201 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1202 self._testFunc, self._description))
1203
1204 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001205 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001206 self._testFunc.__name__)
1207
1208 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001209 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001210 self._testFunc)
1211
1212 def shortDescription(self):
1213 if self._description is not None:
1214 return self._description
1215 doc = self._testFunc.__doc__
1216 return doc and doc.split("\n")[0].strip() or None