blob: 01c5a7bc2f4769edde2cae6d633d5c0b55513ed7 [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 Melottied3a7d22010-12-01 02:32:32 +0000107 expected_regex=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000108 self.expected = expected
109 self.failureException = test_case.failureException
110 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
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000120
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000121
122class _AssertRaisesContext(_AssertRaisesBaseContext):
123 """A context manager used to implement TestCase.assertRaises* methods."""
124
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000125 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000126 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000127
128 def __exit__(self, exc_type, exc_value, tb):
129 if exc_type is None:
130 try:
131 exc_name = self.expected.__name__
132 except AttributeError:
133 exc_name = str(self.expected)
134 if self.obj_name:
135 raise self.failureException("{0} not raised by {1}"
136 .format(exc_name, self.obj_name))
137 else:
138 raise self.failureException("{0} not raised"
139 .format(exc_name))
140 if not issubclass(exc_type, self.expected):
141 # let unexpected exceptions pass through
142 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000143 # store exception, without traceback, for later retrieval
144 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000145 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000146 return True
147
Ezio Melottied3a7d22010-12-01 02:32:32 +0000148 expected_regex = self.expected_regex
149 if not expected_regex.search(str(exc_value)):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000150 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000151 (expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000152 return True
153
154
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000155class _AssertWarnsContext(_AssertRaisesBaseContext):
156 """A context manager used to implement TestCase.assertWarns* methods."""
157
158 def __enter__(self):
159 # The __warningregistry__'s need to be in a pristine state for tests
160 # to work properly.
161 for v in sys.modules.values():
162 if getattr(v, '__warningregistry__', None):
163 v.__warningregistry__ = {}
164 self.warnings_manager = warnings.catch_warnings(record=True)
165 self.warnings = self.warnings_manager.__enter__()
166 warnings.simplefilter("always", self.expected)
167 return self
168
169 def __exit__(self, exc_type, exc_value, tb):
170 self.warnings_manager.__exit__(exc_type, exc_value, tb)
171 if exc_type is not None:
172 # let unexpected exceptions pass through
173 return
174 try:
175 exc_name = self.expected.__name__
176 except AttributeError:
177 exc_name = str(self.expected)
178 first_matching = None
179 for m in self.warnings:
180 w = m.message
181 if not isinstance(w, self.expected):
182 continue
183 if first_matching is None:
184 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000185 if (self.expected_regex is not None and
186 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000187 continue
188 # store warning for later retrieval
189 self.warning = w
190 self.filename = m.filename
191 self.lineno = m.lineno
192 return
193 # Now we simply try to choose a helpful failure message
194 if first_matching is not None:
195 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000196 (self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000197 if self.obj_name:
198 raise self.failureException("{0} not triggered by {1}"
199 .format(exc_name, self.obj_name))
200 else:
201 raise self.failureException("{0} not triggered"
202 .format(exc_name))
203
204
Michael Foord8ca6d982010-11-20 15:34:26 +0000205class _TypeEqualityDict(object):
206
207 def __init__(self, testcase):
208 self.testcase = testcase
209 self._store = {}
210
211 def __setitem__(self, key, value):
212 self._store[key] = value
213
214 def __getitem__(self, key):
215 value = self._store[key]
216 if isinstance(value, str):
217 return getattr(self.testcase, value)
218 return value
219
220 def get(self, key, default=None):
221 if key in self._store:
222 return self[key]
223 return default
224
225
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000226class TestCase(object):
227 """A class whose instances are single test cases.
228
229 By default, the test code itself should be placed in a method named
230 'runTest'.
231
232 If the fixture may be used for many test cases, create as
233 many test methods as are needed. When instantiating such a TestCase
234 subclass, specify in the constructor arguments the name of the test method
235 that the instance is to execute.
236
237 Test authors should subclass TestCase for their own tests. Construction
238 and deconstruction of the test's environment ('fixture') can be
239 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
240
241 If it is necessary to override the __init__ method, the base class
242 __init__ method must always be called. It is important that subclasses
243 should not change the signature of their __init__ method, since instances
244 of the classes are instantiated automatically by parts of the framework
245 in order to be run.
246 """
247
248 # This attribute determines which exception will be raised when
249 # the instance's assertion methods fail; test methods raising this
250 # exception will be deemed to have 'failed' rather than 'errored'
251
252 failureException = AssertionError
253
254 # This attribute determines whether long messages (including repr of
255 # objects used in assert methods) will be printed on failure in *addition*
256 # to any explicit message passed.
257
Michael Foord5074df62010-12-03 00:53:09 +0000258 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000259
Michael Foordc41d1412010-06-10 16:17:07 +0000260 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000261 # by assert methods using difflib. It is looked up as an instance attribute
262 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000263
Michael Foord085dfd32010-06-05 12:17:02 +0000264 maxDiff = 80*8
265
Benjamin Peterson847a4112010-03-14 15:04:17 +0000266 # Attribute used by TestSuite for classSetUp
267
268 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000269
270 def __init__(self, methodName='runTest'):
271 """Create an instance of the class that will use the named test
272 method when executed. Raises a ValueError if the instance does
273 not have a method with the specified name.
274 """
275 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000276 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000277 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000278 try:
279 testMethod = getattr(self, methodName)
280 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000281 if methodName != 'runTest':
282 # we allow instantiation with no explicit method name
283 # but not an *incorrect* or missing method name
284 raise ValueError("no such test method in %s: %s" %
285 (self.__class__, methodName))
286 else:
287 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000288 self._cleanups = []
289
290 # Map types to custom assertEqual functions that will compare
291 # instances of said type in more detail to generate a more useful
292 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000293 self._type_equality_funcs = _TypeEqualityDict(self)
294 self.addTypeEqualityFunc(dict, 'assertDictEqual')
295 self.addTypeEqualityFunc(list, 'assertListEqual')
296 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
297 self.addTypeEqualityFunc(set, 'assertSetEqual')
298 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
299 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000300
301 def addTypeEqualityFunc(self, typeobj, function):
302 """Add a type specific assertEqual style function to compare a type.
303
304 This method is for use by TestCase subclasses that need to register
305 their own type equality functions to provide nicer error messages.
306
307 Args:
308 typeobj: The data type to call this function on when both values
309 are of the same type in assertEqual().
310 function: The callable taking two arguments and an optional
311 msg= argument that raises self.failureException with a
312 useful error message when the two arguments are not equal.
313 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000314 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000315
316 def addCleanup(self, function, *args, **kwargs):
317 """Add a function, with arguments, to be called when the test is
318 completed. Functions added are called on a LIFO basis and are
319 called after tearDown on test failure or success.
320
321 Cleanup items are called even if setUp fails (unlike tearDown)."""
322 self._cleanups.append((function, args, kwargs))
323
324 def setUp(self):
325 "Hook method for setting up the test fixture before exercising it."
326 pass
327
328 def tearDown(self):
329 "Hook method for deconstructing the test fixture after testing it."
330 pass
331
Benjamin Peterson847a4112010-03-14 15:04:17 +0000332 @classmethod
333 def setUpClass(cls):
334 "Hook method for setting up class fixture before running tests in the class."
335
336 @classmethod
337 def tearDownClass(cls):
338 "Hook method for deconstructing the class fixture after running all tests in the class."
339
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000340 def countTestCases(self):
341 return 1
342
343 def defaultTestResult(self):
344 return result.TestResult()
345
346 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000347 """Returns a one-line description of the test, or None if no
348 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000349
Michael Foord34c94622010-02-10 15:51:42 +0000350 The default implementation of this method returns the first line of
351 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000352 """
Michael Foord34c94622010-02-10 15:51:42 +0000353 doc = self._testMethodDoc
354 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000355
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000356
357 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000358 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000359
360 def __eq__(self, other):
361 if type(self) is not type(other):
362 return NotImplemented
363
364 return self._testMethodName == other._testMethodName
365
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000366 def __hash__(self):
367 return hash((type(self), self._testMethodName))
368
369 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000370 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000371
372 def __repr__(self):
373 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000374 (strclass(self.__class__), self._testMethodName)
375
376 def _addSkip(self, result, reason):
377 addSkip = getattr(result, 'addSkip', None)
378 if addSkip is not None:
379 addSkip(self, reason)
380 else:
381 warnings.warn("TestResult has no addSkip method, skips not reported",
382 RuntimeWarning, 2)
383 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000384
Michael Foordb3468f72010-12-19 03:19:47 +0000385 def _executeTestPart(self, function, outcome, isTest=False):
386 try:
387 function()
388 except KeyboardInterrupt:
389 raise
390 except SkipTest as e:
391 outcome.success = False
392 outcome.skipped = str(e)
393 except _UnexpectedSuccess:
394 exc_info = sys.exc_info()
395 outcome.success = False
396 if isTest:
397 outcome.unexpectedSuccess = exc_info
398 else:
399 outcome.errors.append(exc_info)
400 except _ExpectedFailure:
401 outcome.success = False
402 exc_info = sys.exc_info()
403 if isTest:
404 outcome.expectedFailure = exc_info
405 else:
406 outcome.errors.append(exc_info)
407 except self.failureException:
408 outcome.success = False
409 outcome.failures.append(sys.exc_info())
410 exc_info = sys.exc_info()
411 except:
412 outcome.success = False
413 outcome.errors.append(sys.exc_info())
414
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000415 def run(self, result=None):
416 orig_result = result
417 if result is None:
418 result = self.defaultTestResult()
419 startTestRun = getattr(result, 'startTestRun', None)
420 if startTestRun is not None:
421 startTestRun()
422
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000423 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000424
425 testMethod = getattr(self, self._testMethodName)
426 if (getattr(self.__class__, "__unittest_skip__", False) or
427 getattr(testMethod, "__unittest_skip__", False)):
428 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000429 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000430 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
431 or getattr(testMethod, '__unittest_skip_why__', ''))
432 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000433 finally:
434 result.stopTest(self)
435 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000436 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000437 outcome = _Outcome()
438 self._outcomeForDoCleanups = outcome
439
440 self._executeTestPart(self.setUp, outcome)
441 if outcome.success:
442 self._executeTestPart(testMethod, outcome, isTest=True)
443 self._executeTestPart(self.tearDown, outcome)
444
445 self.doCleanups()
446 if outcome.success:
447 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000449 if outcome.skipped is not None:
450 self._addSkip(result, outcome.skipped)
451 for exc_info in outcome.errors:
452 result.addError(self, exc_info)
453 for exc_info in outcome.failures:
454 result.addFailure(self, exc_info)
455 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000456 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
457 if addUnexpectedSuccess is not None:
458 addUnexpectedSuccess(self)
459 else:
460 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
461 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000462 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000463
Michael Foordb3468f72010-12-19 03:19:47 +0000464 if outcome.expectedFailure is not None:
465 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
466 if addExpectedFailure is not None:
467 addExpectedFailure(self, outcome.expectedFailure)
468 else:
469 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
470 RuntimeWarning)
471 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000472
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000473 finally:
474 result.stopTest(self)
475 if orig_result is None:
476 stopTestRun = getattr(result, 'stopTestRun', None)
477 if stopTestRun is not None:
478 stopTestRun()
479
480 def doCleanups(self):
481 """Execute all cleanup functions. Normally called for you after
482 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000483 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000484 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000485 function, args, kwargs = self._cleanups.pop()
486 part = lambda: function(*args, **kwargs)
487 self._executeTestPart(part, outcome)
488
489 # return this for backwards compatibility
490 # even though we no longer us it internally
491 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000492
493 def __call__(self, *args, **kwds):
494 return self.run(*args, **kwds)
495
496 def debug(self):
497 """Run the test without collecting errors in a TestResult"""
498 self.setUp()
499 getattr(self, self._testMethodName)()
500 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000501 while self._cleanups:
502 function, args, kwargs = self._cleanups.pop(-1)
503 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504
505 def skipTest(self, reason):
506 """Skip this test."""
507 raise SkipTest(reason)
508
509 def fail(self, msg=None):
510 """Fail immediately, with the given message."""
511 raise self.failureException(msg)
512
513 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000514 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000515 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000516 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000517 raise self.failureException(msg)
518
519 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000520 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000521 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000522 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000523 raise self.failureException(msg)
524
525 def _formatMessage(self, msg, standardMsg):
526 """Honour the longMessage attribute when generating failure messages.
527 If longMessage is False this means:
528 * Use only an explicit message if it is provided
529 * Otherwise use the standard message for the assert
530
531 If longMessage is True:
532 * Use the standard message
533 * If an explicit message is provided, plus ' : ' and the explicit message
534 """
535 if not self.longMessage:
536 return msg or standardMsg
537 if msg is None:
538 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000539 try:
540 # don't switch to '{}' formatting in Python 2.X
541 # it changes the way unicode input is handled
542 return '%s : %s' % (standardMsg, msg)
543 except UnicodeDecodeError:
544 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000545
546
547 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
548 """Fail unless an exception of class excClass is thrown
549 by callableObj when invoked with arguments args and keyword
550 arguments kwargs. If a different type of exception is
551 thrown, it will not be caught, and the test case will be
552 deemed to have suffered an error, exactly as for an
553 unexpected exception.
554
555 If called with callableObj omitted or None, will return a
556 context object used like this::
557
Michael Foord1c42b122010-02-05 22:58:21 +0000558 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000559 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000560
561 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000562 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000563 exception after the assertion::
564
565 with self.assertRaises(SomeException) as cm:
566 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000567 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000568 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000569 """
570 context = _AssertRaisesContext(excClass, self, callableObj)
571 if callableObj is None:
572 return context
573 with context:
574 callableObj(*args, **kwargs)
575
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000576 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
577 """Fail unless a warning of class warnClass is triggered
578 by callableObj when invoked with arguments args and keyword
579 arguments kwargs. If a different type of warning is
580 triggered, it will not be handled: depending on the other
581 warning filtering rules in effect, it might be silenced, printed
582 out, or raised as an exception.
583
584 If called with callableObj omitted or None, will return a
585 context object used like this::
586
587 with self.assertWarns(SomeWarning):
588 do_something()
589
590 The context manager keeps a reference to the first matching
591 warning as the 'warning' attribute; similarly, the 'filename'
592 and 'lineno' attributes give you information about the line
593 of Python code from which the warning was triggered.
594 This allows you to inspect the warning after the assertion::
595
596 with self.assertWarns(SomeWarning) as cm:
597 do_something()
598 the_warning = cm.warning
599 self.assertEqual(the_warning.some_attribute, 147)
600 """
601 context = _AssertWarnsContext(expected_warning, self, callable_obj)
602 if callable_obj is None:
603 return context
604 with context:
605 callable_obj(*args, **kwargs)
606
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000607 def _getAssertEqualityFunc(self, first, second):
608 """Get a detailed comparison function for the types of the two args.
609
610 Returns: A callable accepting (first, second, msg=None) that will
611 raise a failure exception if first != second with a useful human
612 readable error message for those types.
613 """
614 #
615 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
616 # and vice versa. I opted for the conservative approach in case
617 # subclasses are not intended to be compared in detail to their super
618 # class instances using a type equality func. This means testing
619 # subtypes won't automagically use the detailed comparison. Callers
620 # should use their type specific assertSpamEqual method to compare
621 # subclasses if the detailed comparison is desired and appropriate.
622 # See the discussion in http://bugs.python.org/issue2578.
623 #
624 if type(first) is type(second):
625 asserter = self._type_equality_funcs.get(type(first))
626 if asserter is not None:
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 Melottiaddc6f52010-12-18 20:00:04 +0000941 def assertDictContainsSubset(self, subset, dictionary, msg=None):
942 """Checks whether dictionary is a superset of subset."""
Raymond Hettinger8ebe27f2010-12-21 19:24:26 +0000943 warnings.warn('assertDictContainsSubset is deprecated',
944 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000945 missing = []
946 mismatched = []
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000947 for key, value in subset.items():
948 if key not in dictionary:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000949 missing.append(key)
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000950 elif value != dictionary[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000951 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000952 (safe_repr(key), safe_repr(value),
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000953 safe_repr(dictionary[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000954
955 if not (missing or mismatched):
956 return
957
958 standardMsg = ''
959 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000960 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
961 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000962 if mismatched:
963 if standardMsg:
964 standardMsg += '; '
965 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
966
967 self.fail(self._formatMessage(msg, standardMsg))
968
969 def assertSameElements(self, expected_seq, actual_seq, msg=None):
970 """An unordered sequence specific comparison.
971
972 Raises with an error message listing which elements of expected_seq
973 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000974
975 Duplicate elements are ignored when comparing *expected_seq* and
976 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
977 set(actual))`` but it works with sequences of unhashable objects as
978 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000979 """
Michael Foord91c9da32010-03-20 17:21:27 +0000980 warnings.warn('assertSameElements is deprecated',
981 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000982 try:
983 expected = set(expected_seq)
984 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000985 missing = sorted(expected.difference(actual))
986 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000987 except TypeError:
988 # Fall back to slower list-compare if any of the objects are
989 # not hashable.
990 expected = list(expected_seq)
991 actual = list(actual_seq)
992 try:
993 expected.sort()
994 actual.sort()
995 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000996 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000997 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000998 else:
999 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001000 errors = []
1001 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001002 errors.append('Expected, but missing:\n %s' %
1003 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001004 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001005 errors.append('Unexpected, but present:\n %s' %
1006 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001007 if errors:
1008 standardMsg = '\n'.join(errors)
1009 self.fail(self._formatMessage(msg, standardMsg))
1010
Michael Foord8442a602010-03-20 16:58:04 +00001011
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001012 def assertCountEqual(self, first, second, msg=None):
1013 """An unordered sequence comparison asserting that the same elements,
1014 regardless of order. If the same element occurs more than once,
1015 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001016
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001017 self.assertEqual(Counter(list(first)),
1018 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001019
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001020 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001021 - [0, 1, 1] and [1, 0, 1] compare equal.
1022 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001023
Michael Foord8442a602010-03-20 16:58:04 +00001024 """
Michael Foorde180d392011-01-28 19:51:48 +00001025 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001026 try:
Michael Foorde180d392011-01-28 19:51:48 +00001027 first = collections.Counter(first_seq)
1028 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001029 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001030 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001031 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001032 else:
Michael Foorde180d392011-01-28 19:51:48 +00001033 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001034 return
Michael Foorde180d392011-01-28 19:51:48 +00001035 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001036
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001037 if differences:
1038 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001039 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001040 diffMsg = '\n'.join(lines)
1041 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1042 msg = self._formatMessage(msg, standardMsg)
1043 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001044
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001045 def assertMultiLineEqual(self, first, second, msg=None):
1046 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001047 self.assertIsInstance(first, str, 'First argument is not a string')
1048 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001049
1050 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001051 firstlines = first.splitlines(True)
1052 secondlines = second.splitlines(True)
1053 if len(firstlines) == 1 and first.strip('\r\n') == first:
1054 firstlines = [first + '\n']
1055 secondlines = [second + '\n']
1056 standardMsg = '%s != %s' % (safe_repr(first, True),
1057 safe_repr(second, True))
1058 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001059 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001060 self.fail(self._formatMessage(msg, standardMsg))
1061
1062 def assertLess(self, a, b, msg=None):
1063 """Just like self.assertTrue(a < b), but with a nicer default message."""
1064 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001065 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001066 self.fail(self._formatMessage(msg, standardMsg))
1067
1068 def assertLessEqual(self, a, b, msg=None):
1069 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1070 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001071 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001072 self.fail(self._formatMessage(msg, standardMsg))
1073
1074 def assertGreater(self, a, b, msg=None):
1075 """Just like self.assertTrue(a > b), but with a nicer default message."""
1076 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001077 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001078 self.fail(self._formatMessage(msg, standardMsg))
1079
1080 def assertGreaterEqual(self, a, b, msg=None):
1081 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1082 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001083 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001084 self.fail(self._formatMessage(msg, standardMsg))
1085
1086 def assertIsNone(self, obj, msg=None):
1087 """Same as self.assertTrue(obj is None), with a nicer default message."""
1088 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001089 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001090 self.fail(self._formatMessage(msg, standardMsg))
1091
1092 def assertIsNotNone(self, obj, msg=None):
1093 """Included for symmetry with assertIsNone."""
1094 if obj is None:
1095 standardMsg = 'unexpectedly None'
1096 self.fail(self._formatMessage(msg, standardMsg))
1097
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001098 def assertIsInstance(self, obj, cls, msg=None):
1099 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1100 default message."""
1101 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001102 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001103 self.fail(self._formatMessage(msg, standardMsg))
1104
1105 def assertNotIsInstance(self, obj, cls, msg=None):
1106 """Included for symmetry with assertIsInstance."""
1107 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001108 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001109 self.fail(self._formatMessage(msg, standardMsg))
1110
Ezio Melottied3a7d22010-12-01 02:32:32 +00001111 def assertRaisesRegex(self, expected_exception, expected_regex,
1112 callable_obj=None, *args, **kwargs):
1113 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001114
1115 Args:
1116 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001117 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001118 to be found in error message.
1119 callable_obj: Function to be called.
1120 args: Extra args.
1121 kwargs: Extra kwargs.
1122 """
1123 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001124 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001125 if callable_obj is None:
1126 return context
1127 with context:
1128 callable_obj(*args, **kwargs)
1129
Ezio Melottied3a7d22010-12-01 02:32:32 +00001130 def assertWarnsRegex(self, expected_warning, expected_regex,
1131 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001132 """Asserts that the message in a triggered warning matches a regexp.
1133 Basic functioning is similar to assertWarns() with the addition
1134 that only warnings whose messages also match the regular expression
1135 are considered successful matches.
1136
1137 Args:
1138 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001139 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001140 to be found in error message.
1141 callable_obj: Function to be called.
1142 args: Extra args.
1143 kwargs: Extra kwargs.
1144 """
1145 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001146 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001147 if callable_obj is None:
1148 return context
1149 with context:
1150 callable_obj(*args, **kwargs)
1151
Ezio Melottied3a7d22010-12-01 02:32:32 +00001152 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001153 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001154 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001155 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001156 expected_regex = re.compile(expected_regex)
1157 if not expected_regex.search(text):
1158 msg = msg or "Regex didn't match"
1159 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001160 raise self.failureException(msg)
1161
Ezio Melotti8f776302010-12-10 02:32:05 +00001162 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001163 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001164 if isinstance(unexpected_regex, (str, bytes)):
1165 unexpected_regex = re.compile(unexpected_regex)
1166 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001167 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001168 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001169 msg = '%s: %r matches %r in %r' % (msg,
1170 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001171 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001172 text)
1173 raise self.failureException(msg)
1174
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001175
Ezio Melottied3a7d22010-12-01 02:32:32 +00001176 def _deprecate(original_func):
1177 def deprecated_func(*args, **kwargs):
1178 warnings.warn(
1179 'Please use {0} instead.'.format(original_func.__name__),
1180 DeprecationWarning, 2)
1181 return original_func(*args, **kwargs)
1182 return deprecated_func
1183
Ezio Melotti361467e2011-04-03 17:37:58 +03001184 # see #9424
Ezio Melottied3a7d22010-12-01 02:32:32 +00001185 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1186 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1187 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1188 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1189 failUnless = assert_ = _deprecate(assertTrue)
1190 failUnlessRaises = _deprecate(assertRaises)
1191 failIf = _deprecate(assertFalse)
1192 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1193 assertRegexpMatches = _deprecate(assertRegex)
1194
1195
1196
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001197class FunctionTestCase(TestCase):
1198 """A test case that wraps a test function.
1199
1200 This is useful for slipping pre-existing test functions into the
1201 unittest framework. Optionally, set-up and tidy-up functions can be
1202 supplied. As with TestCase, the tidy-up ('tearDown') function will
1203 always be called if the set-up ('setUp') function ran successfully.
1204 """
1205
1206 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1207 super(FunctionTestCase, self).__init__()
1208 self._setUpFunc = setUp
1209 self._tearDownFunc = tearDown
1210 self._testFunc = testFunc
1211 self._description = description
1212
1213 def setUp(self):
1214 if self._setUpFunc is not None:
1215 self._setUpFunc()
1216
1217 def tearDown(self):
1218 if self._tearDownFunc is not None:
1219 self._tearDownFunc()
1220
1221 def runTest(self):
1222 self._testFunc()
1223
1224 def id(self):
1225 return self._testFunc.__name__
1226
1227 def __eq__(self, other):
1228 if not isinstance(other, self.__class__):
1229 return NotImplemented
1230
1231 return self._setUpFunc == other._setUpFunc and \
1232 self._tearDownFunc == other._tearDownFunc and \
1233 self._testFunc == other._testFunc and \
1234 self._description == other._description
1235
1236 def __ne__(self, other):
1237 return not self == other
1238
1239 def __hash__(self):
1240 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1241 self._testFunc, self._description))
1242
1243 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001244 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001245 self._testFunc.__name__)
1246
1247 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001248 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001249 self._testFunc)
1250
1251 def shortDescription(self):
1252 if self._description is not None:
1253 return self._description
1254 doc = self._testFunc.__doc__
1255 return doc and doc.split("\n")[0].strip() or None