blob: 5b7c29dd2688e1c00e7dd2dcdc1f719785a1c848 [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
Michael Foord8ca6d982010-11-20 15:34:26 +0000221class _TypeEqualityDict(object):
222
223 def __init__(self, testcase):
224 self.testcase = testcase
225 self._store = {}
226
227 def __setitem__(self, key, value):
228 self._store[key] = value
229
230 def __getitem__(self, key):
231 value = self._store[key]
232 if isinstance(value, str):
233 return getattr(self.testcase, value)
234 return value
235
236 def get(self, key, default=None):
237 if key in self._store:
238 return self[key]
239 return default
240
241
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000242class TestCase(object):
243 """A class whose instances are single test cases.
244
245 By default, the test code itself should be placed in a method named
246 'runTest'.
247
248 If the fixture may be used for many test cases, create as
249 many test methods as are needed. When instantiating such a TestCase
250 subclass, specify in the constructor arguments the name of the test method
251 that the instance is to execute.
252
253 Test authors should subclass TestCase for their own tests. Construction
254 and deconstruction of the test's environment ('fixture') can be
255 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
256
257 If it is necessary to override the __init__ method, the base class
258 __init__ method must always be called. It is important that subclasses
259 should not change the signature of their __init__ method, since instances
260 of the classes are instantiated automatically by parts of the framework
261 in order to be run.
262 """
263
264 # This attribute determines which exception will be raised when
265 # the instance's assertion methods fail; test methods raising this
266 # exception will be deemed to have 'failed' rather than 'errored'
267
268 failureException = AssertionError
269
270 # This attribute determines whether long messages (including repr of
271 # objects used in assert methods) will be printed on failure in *addition*
272 # to any explicit message passed.
273
Michael Foord5074df62010-12-03 00:53:09 +0000274 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000275
Michael Foordc41d1412010-06-10 16:17:07 +0000276 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000277 # by assert methods using difflib. It is looked up as an instance attribute
278 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000279
Michael Foord085dfd32010-06-05 12:17:02 +0000280 maxDiff = 80*8
281
Ezio Melottiedd117f2011-04-27 10:20:38 +0300282 # If a string is longer than _diffThreshold, use normal comparison instead
283 # of difflib. See #11763.
284 _diffThreshold = 2**16
285
Benjamin Peterson847a4112010-03-14 15:04:17 +0000286 # Attribute used by TestSuite for classSetUp
287
288 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000289
290 def __init__(self, methodName='runTest'):
291 """Create an instance of the class that will use the named test
292 method when executed. Raises a ValueError if the instance does
293 not have a method with the specified name.
294 """
295 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000296 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000297 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000298 try:
299 testMethod = getattr(self, methodName)
300 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000301 if methodName != 'runTest':
302 # we allow instantiation with no explicit method name
303 # but not an *incorrect* or missing method name
304 raise ValueError("no such test method in %s: %s" %
305 (self.__class__, methodName))
306 else:
307 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000308 self._cleanups = []
309
310 # Map types to custom assertEqual functions that will compare
311 # instances of said type in more detail to generate a more useful
312 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000313 self._type_equality_funcs = _TypeEqualityDict(self)
314 self.addTypeEqualityFunc(dict, 'assertDictEqual')
315 self.addTypeEqualityFunc(list, 'assertListEqual')
316 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
317 self.addTypeEqualityFunc(set, 'assertSetEqual')
318 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
319 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000320
321 def addTypeEqualityFunc(self, typeobj, function):
322 """Add a type specific assertEqual style function to compare a type.
323
324 This method is for use by TestCase subclasses that need to register
325 their own type equality functions to provide nicer error messages.
326
327 Args:
328 typeobj: The data type to call this function on when both values
329 are of the same type in assertEqual().
330 function: The callable taking two arguments and an optional
331 msg= argument that raises self.failureException with a
332 useful error message when the two arguments are not equal.
333 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000334 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000335
336 def addCleanup(self, function, *args, **kwargs):
337 """Add a function, with arguments, to be called when the test is
338 completed. Functions added are called on a LIFO basis and are
339 called after tearDown on test failure or success.
340
341 Cleanup items are called even if setUp fails (unlike tearDown)."""
342 self._cleanups.append((function, args, kwargs))
343
344 def setUp(self):
345 "Hook method for setting up the test fixture before exercising it."
346 pass
347
348 def tearDown(self):
349 "Hook method for deconstructing the test fixture after testing it."
350 pass
351
Benjamin Peterson847a4112010-03-14 15:04:17 +0000352 @classmethod
353 def setUpClass(cls):
354 "Hook method for setting up class fixture before running tests in the class."
355
356 @classmethod
357 def tearDownClass(cls):
358 "Hook method for deconstructing the class fixture after running all tests in the class."
359
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000360 def countTestCases(self):
361 return 1
362
363 def defaultTestResult(self):
364 return result.TestResult()
365
366 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000367 """Returns a one-line description of the test, or None if no
368 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000369
Michael Foord34c94622010-02-10 15:51:42 +0000370 The default implementation of this method returns the first line of
371 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000372 """
Michael Foord34c94622010-02-10 15:51:42 +0000373 doc = self._testMethodDoc
374 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000375
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000376
377 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000378 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000379
380 def __eq__(self, other):
381 if type(self) is not type(other):
382 return NotImplemented
383
384 return self._testMethodName == other._testMethodName
385
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000386 def __hash__(self):
387 return hash((type(self), self._testMethodName))
388
389 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000390 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000391
392 def __repr__(self):
393 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000394 (strclass(self.__class__), self._testMethodName)
395
396 def _addSkip(self, result, reason):
397 addSkip = getattr(result, 'addSkip', None)
398 if addSkip is not None:
399 addSkip(self, reason)
400 else:
401 warnings.warn("TestResult has no addSkip method, skips not reported",
402 RuntimeWarning, 2)
403 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000404
Michael Foordb3468f72010-12-19 03:19:47 +0000405 def _executeTestPart(self, function, outcome, isTest=False):
406 try:
407 function()
408 except KeyboardInterrupt:
409 raise
410 except SkipTest as e:
411 outcome.success = False
412 outcome.skipped = str(e)
413 except _UnexpectedSuccess:
414 exc_info = sys.exc_info()
415 outcome.success = False
416 if isTest:
417 outcome.unexpectedSuccess = exc_info
418 else:
419 outcome.errors.append(exc_info)
420 except _ExpectedFailure:
421 outcome.success = False
422 exc_info = sys.exc_info()
423 if isTest:
424 outcome.expectedFailure = exc_info
425 else:
426 outcome.errors.append(exc_info)
427 except self.failureException:
428 outcome.success = False
429 outcome.failures.append(sys.exc_info())
430 exc_info = sys.exc_info()
431 except:
432 outcome.success = False
433 outcome.errors.append(sys.exc_info())
434
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000435 def run(self, result=None):
436 orig_result = result
437 if result is None:
438 result = self.defaultTestResult()
439 startTestRun = getattr(result, 'startTestRun', None)
440 if startTestRun is not None:
441 startTestRun()
442
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000443 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000444
445 testMethod = getattr(self, self._testMethodName)
446 if (getattr(self.__class__, "__unittest_skip__", False) or
447 getattr(testMethod, "__unittest_skip__", False)):
448 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000449 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000450 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
451 or getattr(testMethod, '__unittest_skip_why__', ''))
452 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000453 finally:
454 result.stopTest(self)
455 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000456 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000457 outcome = _Outcome()
458 self._outcomeForDoCleanups = outcome
459
460 self._executeTestPart(self.setUp, outcome)
461 if outcome.success:
462 self._executeTestPart(testMethod, outcome, isTest=True)
463 self._executeTestPart(self.tearDown, outcome)
464
465 self.doCleanups()
466 if outcome.success:
467 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000468 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000469 if outcome.skipped is not None:
470 self._addSkip(result, outcome.skipped)
471 for exc_info in outcome.errors:
472 result.addError(self, exc_info)
473 for exc_info in outcome.failures:
474 result.addFailure(self, exc_info)
475 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000476 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
477 if addUnexpectedSuccess is not None:
478 addUnexpectedSuccess(self)
479 else:
480 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
481 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000482 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000483
Michael Foordb3468f72010-12-19 03:19:47 +0000484 if outcome.expectedFailure is not None:
485 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
486 if addExpectedFailure is not None:
487 addExpectedFailure(self, outcome.expectedFailure)
488 else:
489 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
490 RuntimeWarning)
491 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400492 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000493 finally:
494 result.stopTest(self)
495 if orig_result is None:
496 stopTestRun = getattr(result, 'stopTestRun', None)
497 if stopTestRun is not None:
498 stopTestRun()
499
500 def doCleanups(self):
501 """Execute all cleanup functions. Normally called for you after
502 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000503 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000505 function, args, kwargs = self._cleanups.pop()
506 part = lambda: function(*args, **kwargs)
507 self._executeTestPart(part, outcome)
508
509 # return this for backwards compatibility
510 # even though we no longer us it internally
511 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000512
513 def __call__(self, *args, **kwds):
514 return self.run(*args, **kwds)
515
516 def debug(self):
517 """Run the test without collecting errors in a TestResult"""
518 self.setUp()
519 getattr(self, self._testMethodName)()
520 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000521 while self._cleanups:
522 function, args, kwargs = self._cleanups.pop(-1)
523 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000524
525 def skipTest(self, reason):
526 """Skip this test."""
527 raise SkipTest(reason)
528
529 def fail(self, msg=None):
530 """Fail immediately, with the given message."""
531 raise self.failureException(msg)
532
533 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000534 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000535 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000536 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000537 raise self.failureException(msg)
538
539 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000540 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000541 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000542 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000543 raise self.failureException(msg)
544
545 def _formatMessage(self, msg, standardMsg):
546 """Honour the longMessage attribute when generating failure messages.
547 If longMessage is False this means:
548 * Use only an explicit message if it is provided
549 * Otherwise use the standard message for the assert
550
551 If longMessage is True:
552 * Use the standard message
553 * If an explicit message is provided, plus ' : ' and the explicit message
554 """
555 if not self.longMessage:
556 return msg or standardMsg
557 if msg is None:
558 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000559 try:
560 # don't switch to '{}' formatting in Python 2.X
561 # it changes the way unicode input is handled
562 return '%s : %s' % (standardMsg, msg)
563 except UnicodeDecodeError:
564 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000565
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000566 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
567 """Fail unless an exception of class excClass is thrown
568 by callableObj when invoked with arguments args and keyword
569 arguments kwargs. If a different type of exception is
570 thrown, it will not be caught, and the test case will be
571 deemed to have suffered an error, exactly as for an
572 unexpected exception.
573
574 If called with callableObj omitted or None, will return a
575 context object used like this::
576
Michael Foord1c42b122010-02-05 22:58:21 +0000577 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000578 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000579
Ezio Melottib4dc2502011-05-06 15:01:41 +0300580 An optional keyword argument 'msg' can be provided when assertRaises
581 is used as a context object.
582
Michael Foord1c42b122010-02-05 22:58:21 +0000583 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000584 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000585 exception after the assertion::
586
587 with self.assertRaises(SomeException) as cm:
588 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000589 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000590 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000591 """
592 context = _AssertRaisesContext(excClass, self, callableObj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300593 return context.handle('assertRaises', callableObj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000594
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000595 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
596 """Fail unless a warning of class warnClass is triggered
Ezio Melottib4dc2502011-05-06 15:01:41 +0300597 by callable_obj when invoked with arguments args and keyword
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000598 arguments kwargs. If a different type of warning is
599 triggered, it will not be handled: depending on the other
600 warning filtering rules in effect, it might be silenced, printed
601 out, or raised as an exception.
602
Ezio Melottib4dc2502011-05-06 15:01:41 +0300603 If called with callable_obj omitted or None, will return a
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000604 context object used like this::
605
606 with self.assertWarns(SomeWarning):
607 do_something()
608
Ezio Melottib4dc2502011-05-06 15:01:41 +0300609 An optional keyword argument 'msg' can be provided when assertWarns
610 is used as a context object.
611
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000612 The context manager keeps a reference to the first matching
613 warning as the 'warning' attribute; similarly, the 'filename'
614 and 'lineno' attributes give you information about the line
615 of Python code from which the warning was triggered.
616 This allows you to inspect the warning after the assertion::
617
618 with self.assertWarns(SomeWarning) as cm:
619 do_something()
620 the_warning = cm.warning
621 self.assertEqual(the_warning.some_attribute, 147)
622 """
623 context = _AssertWarnsContext(expected_warning, self, callable_obj)
Ezio Melottib4dc2502011-05-06 15:01:41 +0300624 return context.handle('assertWarns', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000625
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000626 def _getAssertEqualityFunc(self, first, second):
627 """Get a detailed comparison function for the types of the two args.
628
629 Returns: A callable accepting (first, second, msg=None) that will
630 raise a failure exception if first != second with a useful human
631 readable error message for those types.
632 """
633 #
634 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
635 # and vice versa. I opted for the conservative approach in case
636 # subclasses are not intended to be compared in detail to their super
637 # class instances using a type equality func. This means testing
638 # subtypes won't automagically use the detailed comparison. Callers
639 # should use their type specific assertSpamEqual method to compare
640 # subclasses if the detailed comparison is desired and appropriate.
641 # See the discussion in http://bugs.python.org/issue2578.
642 #
643 if type(first) is type(second):
644 asserter = self._type_equality_funcs.get(type(first))
645 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000646 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000647
648 return self._baseAssertEqual
649
650 def _baseAssertEqual(self, first, second, msg=None):
651 """The default assertEqual implementation, not type specific."""
652 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000653 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000654 msg = self._formatMessage(msg, standardMsg)
655 raise self.failureException(msg)
656
657 def assertEqual(self, first, second, msg=None):
658 """Fail if the two objects are unequal as determined by the '=='
659 operator.
660 """
661 assertion_func = self._getAssertEqualityFunc(first, second)
662 assertion_func(first, second, msg=msg)
663
664 def assertNotEqual(self, first, second, msg=None):
665 """Fail if the two objects are equal as determined by the '=='
666 operator.
667 """
668 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000669 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
670 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000671 raise self.failureException(msg)
672
Michael Foord321d0592010-11-02 13:44:51 +0000673 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000674 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000675 """Fail if the two objects are unequal as determined by their
676 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000677 (default 7) and comparing to zero, or by comparing that the
678 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000679
680 Note that decimal places (from zero) are usually not the same
681 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000682
683 If the two objects compare equal then they will automatically
684 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000685 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000686 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000687 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000688 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000689 if delta is not None and places is not None:
690 raise TypeError("specify delta or places not both")
691
692 if delta is not None:
693 if abs(first - second) <= delta:
694 return
695
696 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
697 safe_repr(second),
698 safe_repr(delta))
699 else:
700 if places is None:
701 places = 7
702
703 if round(abs(second-first), places) == 0:
704 return
705
Benjamin Peterson847a4112010-03-14 15:04:17 +0000706 standardMsg = '%s != %s within %r places' % (safe_repr(first),
707 safe_repr(second),
708 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000709 msg = self._formatMessage(msg, standardMsg)
710 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000711
Michael Foord321d0592010-11-02 13:44:51 +0000712 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000713 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000714 """Fail if the two objects are equal as determined by their
715 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000716 (default 7) and comparing to zero, or by comparing that the
717 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000718
719 Note that decimal places (from zero) are usually not the same
720 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000721
722 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000723 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000724 if delta is not None and places is not None:
725 raise TypeError("specify delta or places not both")
726 if delta is not None:
727 if not (first == second) and abs(first - second) > delta:
728 return
729 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
730 safe_repr(second),
731 safe_repr(delta))
732 else:
733 if places is None:
734 places = 7
735 if not (first == second) and round(abs(second-first), places) != 0:
736 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000737 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000738 safe_repr(second),
739 places)
740
741 msg = self._formatMessage(msg, standardMsg)
742 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000743
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000744
Michael Foord085dfd32010-06-05 12:17:02 +0000745 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000746 """An equality assertion for ordered sequences (like lists and tuples).
747
R. David Murrayad13f222010-01-29 22:17:58 +0000748 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000749 which can be indexed, has a length, and has an equality operator.
750
751 Args:
752 seq1: The first sequence to compare.
753 seq2: The second sequence to compare.
754 seq_type: The expected datatype of the sequences, or None if no
755 datatype should be enforced.
756 msg: Optional message to use on failure instead of a list of
757 differences.
758 """
759 if seq_type != None:
760 seq_type_name = seq_type.__name__
761 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000762 raise self.failureException('First sequence is not a %s: %s'
763 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000764 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000765 raise self.failureException('Second sequence is not a %s: %s'
766 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000767 else:
768 seq_type_name = "sequence"
769
770 differing = None
771 try:
772 len1 = len(seq1)
773 except (TypeError, NotImplementedError):
774 differing = 'First %s has no length. Non-sequence?' % (
775 seq_type_name)
776
777 if differing is None:
778 try:
779 len2 = len(seq2)
780 except (TypeError, NotImplementedError):
781 differing = 'Second %s has no length. Non-sequence?' % (
782 seq_type_name)
783
784 if differing is None:
785 if seq1 == seq2:
786 return
787
Benjamin Peterson847a4112010-03-14 15:04:17 +0000788 seq1_repr = safe_repr(seq1)
789 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000790 if len(seq1_repr) > 30:
791 seq1_repr = seq1_repr[:30] + '...'
792 if len(seq2_repr) > 30:
793 seq2_repr = seq2_repr[:30] + '...'
794 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
795 differing = '%ss differ: %s != %s\n' % elements
796
797 for i in range(min(len1, len2)):
798 try:
799 item1 = seq1[i]
800 except (TypeError, IndexError, NotImplementedError):
801 differing += ('\nUnable to index element %d of first %s\n' %
802 (i, seq_type_name))
803 break
804
805 try:
806 item2 = seq2[i]
807 except (TypeError, IndexError, NotImplementedError):
808 differing += ('\nUnable to index element %d of second %s\n' %
809 (i, seq_type_name))
810 break
811
812 if item1 != item2:
813 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
814 (i, item1, item2))
815 break
816 else:
817 if (len1 == len2 and seq_type is None and
818 type(seq1) != type(seq2)):
819 # The sequences are the same, but have differing types.
820 return
821
822 if len1 > len2:
823 differing += ('\nFirst %s contains %d additional '
824 'elements.\n' % (seq_type_name, len1 - len2))
825 try:
826 differing += ('First extra element %d:\n%s\n' %
827 (len2, seq1[len2]))
828 except (TypeError, IndexError, NotImplementedError):
829 differing += ('Unable to index element %d '
830 'of first %s\n' % (len2, seq_type_name))
831 elif len1 < len2:
832 differing += ('\nSecond %s contains %d additional '
833 'elements.\n' % (seq_type_name, len2 - len1))
834 try:
835 differing += ('First extra element %d:\n%s\n' %
836 (len1, seq2[len1]))
837 except (TypeError, IndexError, NotImplementedError):
838 differing += ('Unable to index element %d '
839 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000840 standardMsg = differing
841 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000842 difflib.ndiff(pprint.pformat(seq1).splitlines(),
843 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000844
845 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000846 msg = self._formatMessage(msg, standardMsg)
847 self.fail(msg)
848
Michael Foord085dfd32010-06-05 12:17:02 +0000849 def _truncateMessage(self, message, diff):
850 max_diff = self.maxDiff
851 if max_diff is None or len(diff) <= max_diff:
852 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000853 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000854
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000855 def assertListEqual(self, list1, list2, msg=None):
856 """A list-specific equality assertion.
857
858 Args:
859 list1: The first list to compare.
860 list2: The second list to compare.
861 msg: Optional message to use on failure instead of a list of
862 differences.
863
864 """
865 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
866
867 def assertTupleEqual(self, tuple1, tuple2, msg=None):
868 """A tuple-specific equality assertion.
869
870 Args:
871 tuple1: The first tuple to compare.
872 tuple2: The second tuple to compare.
873 msg: Optional message to use on failure instead of a list of
874 differences.
875 """
876 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
877
878 def assertSetEqual(self, set1, set2, msg=None):
879 """A set-specific equality assertion.
880
881 Args:
882 set1: The first set to compare.
883 set2: The second set to compare.
884 msg: Optional message to use on failure instead of a list of
885 differences.
886
Michael Foord91c9da32010-03-20 17:21:27 +0000887 assertSetEqual uses ducktyping to support different types of sets, and
888 is optimized for sets specifically (parameters must support a
889 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000890 """
891 try:
892 difference1 = set1.difference(set2)
893 except TypeError as e:
894 self.fail('invalid type when attempting set difference: %s' % e)
895 except AttributeError as e:
896 self.fail('first argument does not support set difference: %s' % e)
897
898 try:
899 difference2 = set2.difference(set1)
900 except TypeError as e:
901 self.fail('invalid type when attempting set difference: %s' % e)
902 except AttributeError as e:
903 self.fail('second argument does not support set difference: %s' % e)
904
905 if not (difference1 or difference2):
906 return
907
908 lines = []
909 if difference1:
910 lines.append('Items in the first set but not the second:')
911 for item in difference1:
912 lines.append(repr(item))
913 if difference2:
914 lines.append('Items in the second set but not the first:')
915 for item in difference2:
916 lines.append(repr(item))
917
918 standardMsg = '\n'.join(lines)
919 self.fail(self._formatMessage(msg, standardMsg))
920
921 def assertIn(self, member, container, msg=None):
922 """Just like self.assertTrue(a in b), but with a nicer default message."""
923 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000924 standardMsg = '%s not found in %s' % (safe_repr(member),
925 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000926 self.fail(self._formatMessage(msg, standardMsg))
927
928 def assertNotIn(self, member, container, msg=None):
929 """Just like self.assertTrue(a not in b), but with a nicer default message."""
930 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000931 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
932 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000933 self.fail(self._formatMessage(msg, standardMsg))
934
935 def assertIs(self, expr1, expr2, msg=None):
936 """Just like self.assertTrue(a is b), but with a nicer default message."""
937 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000938 standardMsg = '%s is not %s' % (safe_repr(expr1),
939 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000940 self.fail(self._formatMessage(msg, standardMsg))
941
942 def assertIsNot(self, expr1, expr2, msg=None):
943 """Just like self.assertTrue(a is not b), but with a nicer default message."""
944 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000945 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000946 self.fail(self._formatMessage(msg, standardMsg))
947
948 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000949 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
950 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000951
952 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000953 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000954 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000955 pprint.pformat(d1).splitlines(),
956 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000957 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000958 self.fail(self._formatMessage(msg, standardMsg))
959
Ezio Melotti0f535012011-04-03 18:02:13 +0300960 def assertDictContainsSubset(self, subset, dictionary, msg=None):
961 """Checks whether dictionary is a superset of subset."""
962 warnings.warn('assertDictContainsSubset is deprecated',
963 DeprecationWarning)
964 missing = []
965 mismatched = []
966 for key, value in subset.items():
967 if key not in dictionary:
968 missing.append(key)
969 elif value != dictionary[key]:
970 mismatched.append('%s, expected: %s, actual: %s' %
971 (safe_repr(key), safe_repr(value),
972 safe_repr(dictionary[key])))
973
974 if not (missing or mismatched):
975 return
976
977 standardMsg = ''
978 if missing:
979 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
980 missing)
981 if mismatched:
982 if standardMsg:
983 standardMsg += '; '
984 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
985
986 self.fail(self._formatMessage(msg, standardMsg))
987
988
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000989 def assertCountEqual(self, first, second, msg=None):
990 """An unordered sequence comparison asserting that the same elements,
991 regardless of order. If the same element occurs more than once,
992 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000993
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000994 self.assertEqual(Counter(list(first)),
995 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000996
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000997 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000998 - [0, 1, 1] and [1, 0, 1] compare equal.
999 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001000
Michael Foord8442a602010-03-20 16:58:04 +00001001 """
Michael Foorde180d392011-01-28 19:51:48 +00001002 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001003 try:
Michael Foorde180d392011-01-28 19:51:48 +00001004 first = collections.Counter(first_seq)
1005 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001006 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001007 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001008 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001009 else:
Michael Foorde180d392011-01-28 19:51:48 +00001010 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001011 return
Michael Foorde180d392011-01-28 19:51:48 +00001012 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001013
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001014 if differences:
1015 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001016 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001017 diffMsg = '\n'.join(lines)
1018 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1019 msg = self._formatMessage(msg, standardMsg)
1020 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001021
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001022 def assertMultiLineEqual(self, first, second, msg=None):
1023 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001024 self.assertIsInstance(first, str, 'First argument is not a string')
1025 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001026
1027 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001028 # don't use difflib if the strings are too long
1029 if (len(first) > self._diffThreshold or
1030 len(second) > self._diffThreshold):
1031 self._baseAssertEqual(first, second, msg)
Michael Foordc653ce32010-07-10 13:52:22 +00001032 firstlines = first.splitlines(True)
1033 secondlines = second.splitlines(True)
1034 if len(firstlines) == 1 and first.strip('\r\n') == first:
1035 firstlines = [first + '\n']
1036 secondlines = [second + '\n']
1037 standardMsg = '%s != %s' % (safe_repr(first, True),
1038 safe_repr(second, True))
1039 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001040 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001041 self.fail(self._formatMessage(msg, standardMsg))
1042
1043 def assertLess(self, a, b, msg=None):
1044 """Just like self.assertTrue(a < b), but with a nicer default message."""
1045 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001046 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001047 self.fail(self._formatMessage(msg, standardMsg))
1048
1049 def assertLessEqual(self, a, b, msg=None):
1050 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1051 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001052 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001053 self.fail(self._formatMessage(msg, standardMsg))
1054
1055 def assertGreater(self, a, b, msg=None):
1056 """Just like self.assertTrue(a > b), but with a nicer default message."""
1057 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001058 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001059 self.fail(self._formatMessage(msg, standardMsg))
1060
1061 def assertGreaterEqual(self, a, b, msg=None):
1062 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1063 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001064 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001065 self.fail(self._formatMessage(msg, standardMsg))
1066
1067 def assertIsNone(self, obj, msg=None):
1068 """Same as self.assertTrue(obj is None), with a nicer default message."""
1069 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001070 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001071 self.fail(self._formatMessage(msg, standardMsg))
1072
1073 def assertIsNotNone(self, obj, msg=None):
1074 """Included for symmetry with assertIsNone."""
1075 if obj is None:
1076 standardMsg = 'unexpectedly None'
1077 self.fail(self._formatMessage(msg, standardMsg))
1078
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001079 def assertIsInstance(self, obj, cls, msg=None):
1080 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1081 default message."""
1082 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001083 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001084 self.fail(self._formatMessage(msg, standardMsg))
1085
1086 def assertNotIsInstance(self, obj, cls, msg=None):
1087 """Included for symmetry with assertIsInstance."""
1088 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001089 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001090 self.fail(self._formatMessage(msg, standardMsg))
1091
Ezio Melottied3a7d22010-12-01 02:32:32 +00001092 def assertRaisesRegex(self, expected_exception, expected_regex,
1093 callable_obj=None, *args, **kwargs):
1094 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001095
1096 Args:
1097 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001098 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001099 to be found in error message.
1100 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001101 msg: Optional message used in case of failure. Can only be used
1102 when assertRaisesRegex is used as a context manager.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001103 args: Extra args.
1104 kwargs: Extra kwargs.
1105 """
1106 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001107 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001108
1109 return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001110
Ezio Melottied3a7d22010-12-01 02:32:32 +00001111 def assertWarnsRegex(self, expected_warning, expected_regex,
1112 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001113 """Asserts that the message in a triggered warning matches a regexp.
1114 Basic functioning is similar to assertWarns() with the addition
1115 that only warnings whose messages also match the regular expression
1116 are considered successful matches.
1117
1118 Args:
1119 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001120 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001121 to be found in error message.
1122 callable_obj: Function to be called.
Ezio Melottib4dc2502011-05-06 15:01:41 +03001123 msg: Optional message used in case of failure. Can only be used
1124 when assertWarnsRegex is used as a context manager.
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001125 args: Extra args.
1126 kwargs: Extra kwargs.
1127 """
1128 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001129 expected_regex)
Ezio Melottib4dc2502011-05-06 15:01:41 +03001130 return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001131
Ezio Melottied3a7d22010-12-01 02:32:32 +00001132 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001133 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001134 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001135 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001136 expected_regex = re.compile(expected_regex)
1137 if not expected_regex.search(text):
1138 msg = msg or "Regex didn't match"
1139 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001140 raise self.failureException(msg)
1141
Ezio Melotti8f776302010-12-10 02:32:05 +00001142 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001143 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001144 if isinstance(unexpected_regex, (str, bytes)):
1145 unexpected_regex = re.compile(unexpected_regex)
1146 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001147 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001148 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001149 msg = '%s: %r matches %r in %r' % (msg,
1150 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001151 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001152 text)
1153 raise self.failureException(msg)
1154
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001155
Ezio Melottied3a7d22010-12-01 02:32:32 +00001156 def _deprecate(original_func):
1157 def deprecated_func(*args, **kwargs):
1158 warnings.warn(
1159 'Please use {0} instead.'.format(original_func.__name__),
1160 DeprecationWarning, 2)
1161 return original_func(*args, **kwargs)
1162 return deprecated_func
1163
Ezio Melotti361467e2011-04-03 17:37:58 +03001164 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001165 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1166 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1167 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1168 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1169 failUnless = assert_ = _deprecate(assertTrue)
1170 failUnlessRaises = _deprecate(assertRaises)
1171 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001172 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1173 assertRegexpMatches = _deprecate(assertRegex)
1174
1175
1176
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001177class FunctionTestCase(TestCase):
1178 """A test case that wraps a test function.
1179
1180 This is useful for slipping pre-existing test functions into the
1181 unittest framework. Optionally, set-up and tidy-up functions can be
1182 supplied. As with TestCase, the tidy-up ('tearDown') function will
1183 always be called if the set-up ('setUp') function ran successfully.
1184 """
1185
1186 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1187 super(FunctionTestCase, self).__init__()
1188 self._setUpFunc = setUp
1189 self._tearDownFunc = tearDown
1190 self._testFunc = testFunc
1191 self._description = description
1192
1193 def setUp(self):
1194 if self._setUpFunc is not None:
1195 self._setUpFunc()
1196
1197 def tearDown(self):
1198 if self._tearDownFunc is not None:
1199 self._tearDownFunc()
1200
1201 def runTest(self):
1202 self._testFunc()
1203
1204 def id(self):
1205 return self._testFunc.__name__
1206
1207 def __eq__(self, other):
1208 if not isinstance(other, self.__class__):
1209 return NotImplemented
1210
1211 return self._setUpFunc == other._setUpFunc and \
1212 self._tearDownFunc == other._tearDownFunc and \
1213 self._testFunc == other._testFunc and \
1214 self._description == other._description
1215
1216 def __ne__(self, other):
1217 return not self == other
1218
1219 def __hash__(self):
1220 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1221 self._testFunc, self._description))
1222
1223 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001224 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001225 self._testFunc.__name__)
1226
1227 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001228 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001229 self._testFunc)
1230
1231 def shortDescription(self):
1232 if self._description is not None:
1233 return self._description
1234 doc = self._testFunc.__doc__
1235 return doc and doc.split("\n")[0].strip() or None