blob: 3133907e4a9a39cbbc65bc7ff6bd137a0de5ca86 [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
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000205class TestCase(object):
206 """A class whose instances are single test cases.
207
208 By default, the test code itself should be placed in a method named
209 'runTest'.
210
211 If the fixture may be used for many test cases, create as
212 many test methods as are needed. When instantiating such a TestCase
213 subclass, specify in the constructor arguments the name of the test method
214 that the instance is to execute.
215
216 Test authors should subclass TestCase for their own tests. Construction
217 and deconstruction of the test's environment ('fixture') can be
218 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
219
220 If it is necessary to override the __init__ method, the base class
221 __init__ method must always be called. It is important that subclasses
222 should not change the signature of their __init__ method, since instances
223 of the classes are instantiated automatically by parts of the framework
224 in order to be run.
225 """
226
227 # This attribute determines which exception will be raised when
228 # the instance's assertion methods fail; test methods raising this
229 # exception will be deemed to have 'failed' rather than 'errored'
230
231 failureException = AssertionError
232
233 # This attribute determines whether long messages (including repr of
234 # objects used in assert methods) will be printed on failure in *addition*
235 # to any explicit message passed.
236
Michael Foord5074df62010-12-03 00:53:09 +0000237 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000238
Michael Foordc41d1412010-06-10 16:17:07 +0000239 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000240 # by assert methods using difflib. It is looked up as an instance attribute
241 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000242
Michael Foord085dfd32010-06-05 12:17:02 +0000243 maxDiff = 80*8
244
Ezio Melottiedd117f2011-04-27 10:20:38 +0300245 # If a string is longer than _diffThreshold, use normal comparison instead
246 # of difflib. See #11763.
247 _diffThreshold = 2**16
248
Benjamin Peterson847a4112010-03-14 15:04:17 +0000249 # Attribute used by TestSuite for classSetUp
250
251 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000252
253 def __init__(self, methodName='runTest'):
254 """Create an instance of the class that will use the named test
255 method when executed. Raises a ValueError if the instance does
256 not have a method with the specified name.
257 """
258 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000259 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000260 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000261 try:
262 testMethod = getattr(self, methodName)
263 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000264 if methodName != 'runTest':
265 # we allow instantiation with no explicit method name
266 # but not an *incorrect* or missing method name
267 raise ValueError("no such test method in %s: %s" %
268 (self.__class__, methodName))
269 else:
270 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000271 self._cleanups = []
272
273 # Map types to custom assertEqual functions that will compare
274 # instances of said type in more detail to generate a more useful
275 # error message.
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500276 self._type_equality_funcs = {}
Michael Foord8ca6d982010-11-20 15:34:26 +0000277 self.addTypeEqualityFunc(dict, 'assertDictEqual')
278 self.addTypeEqualityFunc(list, 'assertListEqual')
279 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
280 self.addTypeEqualityFunc(set, 'assertSetEqual')
281 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
282 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000283
284 def addTypeEqualityFunc(self, typeobj, function):
285 """Add a type specific assertEqual style function to compare a type.
286
287 This method is for use by TestCase subclasses that need to register
288 their own type equality functions to provide nicer error messages.
289
290 Args:
291 typeobj: The data type to call this function on when both values
292 are of the same type in assertEqual().
293 function: The callable taking two arguments and an optional
294 msg= argument that raises self.failureException with a
295 useful error message when the two arguments are not equal.
296 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000297 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000298
299 def addCleanup(self, function, *args, **kwargs):
300 """Add a function, with arguments, to be called when the test is
301 completed. Functions added are called on a LIFO basis and are
302 called after tearDown on test failure or success.
303
304 Cleanup items are called even if setUp fails (unlike tearDown)."""
305 self._cleanups.append((function, args, kwargs))
306
307 def setUp(self):
308 "Hook method for setting up the test fixture before exercising it."
309 pass
310
311 def tearDown(self):
312 "Hook method for deconstructing the test fixture after testing it."
313 pass
314
Benjamin Peterson847a4112010-03-14 15:04:17 +0000315 @classmethod
316 def setUpClass(cls):
317 "Hook method for setting up class fixture before running tests in the class."
318
319 @classmethod
320 def tearDownClass(cls):
321 "Hook method for deconstructing the class fixture after running all tests in the class."
322
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000323 def countTestCases(self):
324 return 1
325
326 def defaultTestResult(self):
327 return result.TestResult()
328
329 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000330 """Returns a one-line description of the test, or None if no
331 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000332
Michael Foord34c94622010-02-10 15:51:42 +0000333 The default implementation of this method returns the first line of
334 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000335 """
Michael Foord34c94622010-02-10 15:51:42 +0000336 doc = self._testMethodDoc
337 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000338
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000339
340 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000341 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000342
343 def __eq__(self, other):
344 if type(self) is not type(other):
345 return NotImplemented
346
347 return self._testMethodName == other._testMethodName
348
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000349 def __hash__(self):
350 return hash((type(self), self._testMethodName))
351
352 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000353 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000354
355 def __repr__(self):
356 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000357 (strclass(self.__class__), self._testMethodName)
358
359 def _addSkip(self, result, reason):
360 addSkip = getattr(result, 'addSkip', None)
361 if addSkip is not None:
362 addSkip(self, reason)
363 else:
364 warnings.warn("TestResult has no addSkip method, skips not reported",
365 RuntimeWarning, 2)
366 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000367
Michael Foordb3468f72010-12-19 03:19:47 +0000368 def _executeTestPart(self, function, outcome, isTest=False):
369 try:
370 function()
371 except KeyboardInterrupt:
372 raise
373 except SkipTest as e:
374 outcome.success = False
375 outcome.skipped = str(e)
376 except _UnexpectedSuccess:
377 exc_info = sys.exc_info()
378 outcome.success = False
379 if isTest:
380 outcome.unexpectedSuccess = exc_info
381 else:
382 outcome.errors.append(exc_info)
383 except _ExpectedFailure:
384 outcome.success = False
385 exc_info = sys.exc_info()
386 if isTest:
387 outcome.expectedFailure = exc_info
388 else:
389 outcome.errors.append(exc_info)
390 except self.failureException:
391 outcome.success = False
392 outcome.failures.append(sys.exc_info())
393 exc_info = sys.exc_info()
394 except:
395 outcome.success = False
396 outcome.errors.append(sys.exc_info())
397
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000398 def run(self, result=None):
399 orig_result = result
400 if result is None:
401 result = self.defaultTestResult()
402 startTestRun = getattr(result, 'startTestRun', None)
403 if startTestRun is not None:
404 startTestRun()
405
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000406 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000407
408 testMethod = getattr(self, self._testMethodName)
409 if (getattr(self.__class__, "__unittest_skip__", False) or
410 getattr(testMethod, "__unittest_skip__", False)):
411 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000412 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000413 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
414 or getattr(testMethod, '__unittest_skip_why__', ''))
415 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000416 finally:
417 result.stopTest(self)
418 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000419 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000420 outcome = _Outcome()
421 self._outcomeForDoCleanups = outcome
422
423 self._executeTestPart(self.setUp, outcome)
424 if outcome.success:
425 self._executeTestPart(testMethod, outcome, isTest=True)
426 self._executeTestPart(self.tearDown, outcome)
427
428 self.doCleanups()
429 if outcome.success:
430 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000431 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000432 if outcome.skipped is not None:
433 self._addSkip(result, outcome.skipped)
434 for exc_info in outcome.errors:
435 result.addError(self, exc_info)
436 for exc_info in outcome.failures:
437 result.addFailure(self, exc_info)
438 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000439 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
440 if addUnexpectedSuccess is not None:
441 addUnexpectedSuccess(self)
442 else:
443 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
444 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000445 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000446
Michael Foordb3468f72010-12-19 03:19:47 +0000447 if outcome.expectedFailure is not None:
448 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
449 if addExpectedFailure is not None:
450 addExpectedFailure(self, outcome.expectedFailure)
451 else:
452 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
453 RuntimeWarning)
454 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000455
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000456 finally:
457 result.stopTest(self)
458 if orig_result is None:
459 stopTestRun = getattr(result, 'stopTestRun', None)
460 if stopTestRun is not None:
461 stopTestRun()
462
463 def doCleanups(self):
464 """Execute all cleanup functions. Normally called for you after
465 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000466 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000468 function, args, kwargs = self._cleanups.pop()
469 part = lambda: function(*args, **kwargs)
470 self._executeTestPart(part, outcome)
471
472 # return this for backwards compatibility
473 # even though we no longer us it internally
474 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000475
476 def __call__(self, *args, **kwds):
477 return self.run(*args, **kwds)
478
479 def debug(self):
480 """Run the test without collecting errors in a TestResult"""
481 self.setUp()
482 getattr(self, self._testMethodName)()
483 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000484 while self._cleanups:
485 function, args, kwargs = self._cleanups.pop(-1)
486 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000487
488 def skipTest(self, reason):
489 """Skip this test."""
490 raise SkipTest(reason)
491
492 def fail(self, msg=None):
493 """Fail immediately, with the given message."""
494 raise self.failureException(msg)
495
496 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000497 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000498 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000499 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000500 raise self.failureException(msg)
501
502 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000503 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000505 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000506 raise self.failureException(msg)
507
508 def _formatMessage(self, msg, standardMsg):
509 """Honour the longMessage attribute when generating failure messages.
510 If longMessage is False this means:
511 * Use only an explicit message if it is provided
512 * Otherwise use the standard message for the assert
513
514 If longMessage is True:
515 * Use the standard message
516 * If an explicit message is provided, plus ' : ' and the explicit message
517 """
518 if not self.longMessage:
519 return msg or standardMsg
520 if msg is None:
521 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000522 try:
523 # don't switch to '{}' formatting in Python 2.X
524 # it changes the way unicode input is handled
525 return '%s : %s' % (standardMsg, msg)
526 except UnicodeDecodeError:
527 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000528
529
530 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
531 """Fail unless an exception of class excClass is thrown
532 by callableObj when invoked with arguments args and keyword
533 arguments kwargs. If a different type of exception is
534 thrown, it will not be caught, and the test case will be
535 deemed to have suffered an error, exactly as for an
536 unexpected exception.
537
538 If called with callableObj omitted or None, will return a
539 context object used like this::
540
Michael Foord1c42b122010-02-05 22:58:21 +0000541 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000542 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000543
544 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000545 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000546 exception after the assertion::
547
548 with self.assertRaises(SomeException) as cm:
549 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000550 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000551 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000552 """
553 context = _AssertRaisesContext(excClass, self, callableObj)
554 if callableObj is None:
555 return context
556 with context:
557 callableObj(*args, **kwargs)
558
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000559 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
560 """Fail unless a warning of class warnClass is triggered
561 by callableObj when invoked with arguments args and keyword
562 arguments kwargs. If a different type of warning is
563 triggered, it will not be handled: depending on the other
564 warning filtering rules in effect, it might be silenced, printed
565 out, or raised as an exception.
566
567 If called with callableObj omitted or None, will return a
568 context object used like this::
569
570 with self.assertWarns(SomeWarning):
571 do_something()
572
573 The context manager keeps a reference to the first matching
574 warning as the 'warning' attribute; similarly, the 'filename'
575 and 'lineno' attributes give you information about the line
576 of Python code from which the warning was triggered.
577 This allows you to inspect the warning after the assertion::
578
579 with self.assertWarns(SomeWarning) as cm:
580 do_something()
581 the_warning = cm.warning
582 self.assertEqual(the_warning.some_attribute, 147)
583 """
584 context = _AssertWarnsContext(expected_warning, self, callable_obj)
585 if callable_obj is None:
586 return context
587 with context:
588 callable_obj(*args, **kwargs)
589
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000590 def _getAssertEqualityFunc(self, first, second):
591 """Get a detailed comparison function for the types of the two args.
592
593 Returns: A callable accepting (first, second, msg=None) that will
594 raise a failure exception if first != second with a useful human
595 readable error message for those types.
596 """
597 #
598 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
599 # and vice versa. I opted for the conservative approach in case
600 # subclasses are not intended to be compared in detail to their super
601 # class instances using a type equality func. This means testing
602 # subtypes won't automagically use the detailed comparison. Callers
603 # should use their type specific assertSpamEqual method to compare
604 # subclasses if the detailed comparison is desired and appropriate.
605 # See the discussion in http://bugs.python.org/issue2578.
606 #
607 if type(first) is type(second):
608 asserter = self._type_equality_funcs.get(type(first))
609 if asserter is not None:
Benjamin Peterson34b2b262011-07-12 19:21:42 -0500610 if isinstance(asserter, str):
611 asserter = getattr(self, asserter)
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000612 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000613
614 return self._baseAssertEqual
615
616 def _baseAssertEqual(self, first, second, msg=None):
617 """The default assertEqual implementation, not type specific."""
618 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000619 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000620 msg = self._formatMessage(msg, standardMsg)
621 raise self.failureException(msg)
622
623 def assertEqual(self, first, second, msg=None):
624 """Fail if the two objects are unequal as determined by the '=='
625 operator.
626 """
627 assertion_func = self._getAssertEqualityFunc(first, second)
628 assertion_func(first, second, msg=msg)
629
630 def assertNotEqual(self, first, second, msg=None):
631 """Fail if the two objects are equal as determined by the '=='
632 operator.
633 """
634 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000635 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
636 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000637 raise self.failureException(msg)
638
Michael Foord321d0592010-11-02 13:44:51 +0000639 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000640 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000641 """Fail if the two objects are unequal as determined by their
642 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000643 (default 7) and comparing to zero, or by comparing that the
644 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000645
646 Note that decimal places (from zero) are usually not the same
647 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000648
649 If the two objects compare equal then they will automatically
650 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000651 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000652 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000653 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000654 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000655 if delta is not None and places is not None:
656 raise TypeError("specify delta or places not both")
657
658 if delta is not None:
659 if abs(first - second) <= delta:
660 return
661
662 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
663 safe_repr(second),
664 safe_repr(delta))
665 else:
666 if places is None:
667 places = 7
668
669 if round(abs(second-first), places) == 0:
670 return
671
Benjamin Peterson847a4112010-03-14 15:04:17 +0000672 standardMsg = '%s != %s within %r places' % (safe_repr(first),
673 safe_repr(second),
674 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000675 msg = self._formatMessage(msg, standardMsg)
676 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000677
Michael Foord321d0592010-11-02 13:44:51 +0000678 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000679 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000680 """Fail if the two objects are equal as determined by their
681 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000682 (default 7) and comparing to zero, or by comparing that the
683 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000684
685 Note that decimal places (from zero) are usually not the same
686 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000687
688 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000689 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000690 if delta is not None and places is not None:
691 raise TypeError("specify delta or places not both")
692 if delta is not None:
693 if not (first == second) and abs(first - second) > delta:
694 return
695 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
696 safe_repr(second),
697 safe_repr(delta))
698 else:
699 if places is None:
700 places = 7
701 if not (first == second) and round(abs(second-first), places) != 0:
702 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000703 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000704 safe_repr(second),
705 places)
706
707 msg = self._formatMessage(msg, standardMsg)
708 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000709
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000710
Michael Foord085dfd32010-06-05 12:17:02 +0000711 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000712 """An equality assertion for ordered sequences (like lists and tuples).
713
R. David Murrayad13f222010-01-29 22:17:58 +0000714 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000715 which can be indexed, has a length, and has an equality operator.
716
717 Args:
718 seq1: The first sequence to compare.
719 seq2: The second sequence to compare.
720 seq_type: The expected datatype of the sequences, or None if no
721 datatype should be enforced.
722 msg: Optional message to use on failure instead of a list of
723 differences.
724 """
725 if seq_type != None:
726 seq_type_name = seq_type.__name__
727 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000728 raise self.failureException('First sequence is not a %s: %s'
729 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000730 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000731 raise self.failureException('Second sequence is not a %s: %s'
732 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000733 else:
734 seq_type_name = "sequence"
735
736 differing = None
737 try:
738 len1 = len(seq1)
739 except (TypeError, NotImplementedError):
740 differing = 'First %s has no length. Non-sequence?' % (
741 seq_type_name)
742
743 if differing is None:
744 try:
745 len2 = len(seq2)
746 except (TypeError, NotImplementedError):
747 differing = 'Second %s has no length. Non-sequence?' % (
748 seq_type_name)
749
750 if differing is None:
751 if seq1 == seq2:
752 return
753
Benjamin Peterson847a4112010-03-14 15:04:17 +0000754 seq1_repr = safe_repr(seq1)
755 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000756 if len(seq1_repr) > 30:
757 seq1_repr = seq1_repr[:30] + '...'
758 if len(seq2_repr) > 30:
759 seq2_repr = seq2_repr[:30] + '...'
760 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
761 differing = '%ss differ: %s != %s\n' % elements
762
763 for i in range(min(len1, len2)):
764 try:
765 item1 = seq1[i]
766 except (TypeError, IndexError, NotImplementedError):
767 differing += ('\nUnable to index element %d of first %s\n' %
768 (i, seq_type_name))
769 break
770
771 try:
772 item2 = seq2[i]
773 except (TypeError, IndexError, NotImplementedError):
774 differing += ('\nUnable to index element %d of second %s\n' %
775 (i, seq_type_name))
776 break
777
778 if item1 != item2:
779 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
780 (i, item1, item2))
781 break
782 else:
783 if (len1 == len2 and seq_type is None and
784 type(seq1) != type(seq2)):
785 # The sequences are the same, but have differing types.
786 return
787
788 if len1 > len2:
789 differing += ('\nFirst %s contains %d additional '
790 'elements.\n' % (seq_type_name, len1 - len2))
791 try:
792 differing += ('First extra element %d:\n%s\n' %
793 (len2, seq1[len2]))
794 except (TypeError, IndexError, NotImplementedError):
795 differing += ('Unable to index element %d '
796 'of first %s\n' % (len2, seq_type_name))
797 elif len1 < len2:
798 differing += ('\nSecond %s contains %d additional '
799 'elements.\n' % (seq_type_name, len2 - len1))
800 try:
801 differing += ('First extra element %d:\n%s\n' %
802 (len1, seq2[len1]))
803 except (TypeError, IndexError, NotImplementedError):
804 differing += ('Unable to index element %d '
805 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000806 standardMsg = differing
807 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000808 difflib.ndiff(pprint.pformat(seq1).splitlines(),
809 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000810
811 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000812 msg = self._formatMessage(msg, standardMsg)
813 self.fail(msg)
814
Michael Foord085dfd32010-06-05 12:17:02 +0000815 def _truncateMessage(self, message, diff):
816 max_diff = self.maxDiff
817 if max_diff is None or len(diff) <= max_diff:
818 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000819 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000820
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000821 def assertListEqual(self, list1, list2, msg=None):
822 """A list-specific equality assertion.
823
824 Args:
825 list1: The first list to compare.
826 list2: The second list to compare.
827 msg: Optional message to use on failure instead of a list of
828 differences.
829
830 """
831 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
832
833 def assertTupleEqual(self, tuple1, tuple2, msg=None):
834 """A tuple-specific equality assertion.
835
836 Args:
837 tuple1: The first tuple to compare.
838 tuple2: The second tuple to compare.
839 msg: Optional message to use on failure instead of a list of
840 differences.
841 """
842 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
843
844 def assertSetEqual(self, set1, set2, msg=None):
845 """A set-specific equality assertion.
846
847 Args:
848 set1: The first set to compare.
849 set2: The second set to compare.
850 msg: Optional message to use on failure instead of a list of
851 differences.
852
Michael Foord91c9da32010-03-20 17:21:27 +0000853 assertSetEqual uses ducktyping to support different types of sets, and
854 is optimized for sets specifically (parameters must support a
855 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000856 """
857 try:
858 difference1 = set1.difference(set2)
859 except TypeError as e:
860 self.fail('invalid type when attempting set difference: %s' % e)
861 except AttributeError as e:
862 self.fail('first argument does not support set difference: %s' % e)
863
864 try:
865 difference2 = set2.difference(set1)
866 except TypeError as e:
867 self.fail('invalid type when attempting set difference: %s' % e)
868 except AttributeError as e:
869 self.fail('second argument does not support set difference: %s' % e)
870
871 if not (difference1 or difference2):
872 return
873
874 lines = []
875 if difference1:
876 lines.append('Items in the first set but not the second:')
877 for item in difference1:
878 lines.append(repr(item))
879 if difference2:
880 lines.append('Items in the second set but not the first:')
881 for item in difference2:
882 lines.append(repr(item))
883
884 standardMsg = '\n'.join(lines)
885 self.fail(self._formatMessage(msg, standardMsg))
886
887 def assertIn(self, member, container, msg=None):
888 """Just like self.assertTrue(a in b), but with a nicer default message."""
889 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000890 standardMsg = '%s not found in %s' % (safe_repr(member),
891 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000892 self.fail(self._formatMessage(msg, standardMsg))
893
894 def assertNotIn(self, member, container, msg=None):
895 """Just like self.assertTrue(a not in b), but with a nicer default message."""
896 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000897 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
898 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000899 self.fail(self._formatMessage(msg, standardMsg))
900
901 def assertIs(self, expr1, expr2, msg=None):
902 """Just like self.assertTrue(a is b), but with a nicer default message."""
903 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000904 standardMsg = '%s is not %s' % (safe_repr(expr1),
905 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000906 self.fail(self._formatMessage(msg, standardMsg))
907
908 def assertIsNot(self, expr1, expr2, msg=None):
909 """Just like self.assertTrue(a is not b), but with a nicer default message."""
910 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000911 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000912 self.fail(self._formatMessage(msg, standardMsg))
913
914 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000915 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
916 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000917
918 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000919 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000920 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000921 pprint.pformat(d1).splitlines(),
922 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000923 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000924 self.fail(self._formatMessage(msg, standardMsg))
925
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000926 def assertDictContainsSubset(self, subset, dictionary, msg=None):
927 """Checks whether dictionary is a superset of subset."""
Raymond Hettinger8ebe27f2010-12-21 19:24:26 +0000928 warnings.warn('assertDictContainsSubset is deprecated',
929 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000930 missing = []
931 mismatched = []
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000932 for key, value in subset.items():
933 if key not in dictionary:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000934 missing.append(key)
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000935 elif value != dictionary[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000936 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000937 (safe_repr(key), safe_repr(value),
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000938 safe_repr(dictionary[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000939
940 if not (missing or mismatched):
941 return
942
943 standardMsg = ''
944 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000945 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
946 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000947 if mismatched:
948 if standardMsg:
949 standardMsg += '; '
950 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
951
952 self.fail(self._formatMessage(msg, standardMsg))
953
954 def assertSameElements(self, expected_seq, actual_seq, msg=None):
955 """An unordered sequence specific comparison.
956
957 Raises with an error message listing which elements of expected_seq
958 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000959
960 Duplicate elements are ignored when comparing *expected_seq* and
961 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
962 set(actual))`` but it works with sequences of unhashable objects as
963 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000964 """
Michael Foord91c9da32010-03-20 17:21:27 +0000965 warnings.warn('assertSameElements is deprecated',
966 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000967 try:
968 expected = set(expected_seq)
969 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000970 missing = sorted(expected.difference(actual))
971 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000972 except TypeError:
973 # Fall back to slower list-compare if any of the objects are
974 # not hashable.
975 expected = list(expected_seq)
976 actual = list(actual_seq)
977 try:
978 expected.sort()
979 actual.sort()
980 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000981 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000982 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000983 else:
984 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000985 errors = []
986 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000987 errors.append('Expected, but missing:\n %s' %
988 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000989 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000990 errors.append('Unexpected, but present:\n %s' %
991 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000992 if errors:
993 standardMsg = '\n'.join(errors)
994 self.fail(self._formatMessage(msg, standardMsg))
995
Michael Foord8442a602010-03-20 16:58:04 +0000996
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000997 def assertCountEqual(self, first, second, msg=None):
998 """An unordered sequence comparison asserting that the same elements,
999 regardless of order. If the same element occurs more than once,
1000 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001001
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001002 self.assertEqual(Counter(list(first)),
1003 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001004
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001005 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001006 - [0, 1, 1] and [1, 0, 1] compare equal.
1007 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001008
Michael Foord8442a602010-03-20 16:58:04 +00001009 """
Michael Foorde180d392011-01-28 19:51:48 +00001010 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001011 try:
Michael Foorde180d392011-01-28 19:51:48 +00001012 first = collections.Counter(first_seq)
1013 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001014 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001015 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +00001016 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001017 else:
Michael Foorde180d392011-01-28 19:51:48 +00001018 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001019 return
Michael Foorde180d392011-01-28 19:51:48 +00001020 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001021
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001022 if differences:
1023 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001024 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001025 diffMsg = '\n'.join(lines)
1026 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1027 msg = self._formatMessage(msg, standardMsg)
1028 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001029
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001030 def assertMultiLineEqual(self, first, second, msg=None):
1031 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001032 self.assertIsInstance(first, str, 'First argument is not a string')
1033 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001034
1035 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001036 # don't use difflib if the strings are too long
1037 if (len(first) > self._diffThreshold or
1038 len(second) > self._diffThreshold):
1039 self._baseAssertEqual(first, second, msg)
Michael Foordc653ce32010-07-10 13:52:22 +00001040 firstlines = first.splitlines(True)
1041 secondlines = second.splitlines(True)
1042 if len(firstlines) == 1 and first.strip('\r\n') == first:
1043 firstlines = [first + '\n']
1044 secondlines = [second + '\n']
1045 standardMsg = '%s != %s' % (safe_repr(first, True),
1046 safe_repr(second, True))
1047 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001048 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001049 self.fail(self._formatMessage(msg, standardMsg))
1050
1051 def assertLess(self, a, b, msg=None):
1052 """Just like self.assertTrue(a < b), but with a nicer default message."""
1053 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001054 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001055 self.fail(self._formatMessage(msg, standardMsg))
1056
1057 def assertLessEqual(self, a, b, msg=None):
1058 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1059 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001060 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001061 self.fail(self._formatMessage(msg, standardMsg))
1062
1063 def assertGreater(self, a, b, msg=None):
1064 """Just like self.assertTrue(a > b), but with a nicer default message."""
1065 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001066 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001067 self.fail(self._formatMessage(msg, standardMsg))
1068
1069 def assertGreaterEqual(self, a, b, msg=None):
1070 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1071 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001072 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001073 self.fail(self._formatMessage(msg, standardMsg))
1074
1075 def assertIsNone(self, obj, msg=None):
1076 """Same as self.assertTrue(obj is None), with a nicer default message."""
1077 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001078 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001079 self.fail(self._formatMessage(msg, standardMsg))
1080
1081 def assertIsNotNone(self, obj, msg=None):
1082 """Included for symmetry with assertIsNone."""
1083 if obj is None:
1084 standardMsg = 'unexpectedly None'
1085 self.fail(self._formatMessage(msg, standardMsg))
1086
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001087 def assertIsInstance(self, obj, cls, msg=None):
1088 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1089 default message."""
1090 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001091 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001092 self.fail(self._formatMessage(msg, standardMsg))
1093
1094 def assertNotIsInstance(self, obj, cls, msg=None):
1095 """Included for symmetry with assertIsInstance."""
1096 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001097 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001098 self.fail(self._formatMessage(msg, standardMsg))
1099
Ezio Melottied3a7d22010-12-01 02:32:32 +00001100 def assertRaisesRegex(self, expected_exception, expected_regex,
1101 callable_obj=None, *args, **kwargs):
1102 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001103
1104 Args:
1105 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001106 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001107 to be found in error message.
1108 callable_obj: Function to be called.
1109 args: Extra args.
1110 kwargs: Extra kwargs.
1111 """
1112 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001113 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001114 if callable_obj is None:
1115 return context
1116 with context:
1117 callable_obj(*args, **kwargs)
1118
Ezio Melottied3a7d22010-12-01 02:32:32 +00001119 def assertWarnsRegex(self, expected_warning, expected_regex,
1120 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001121 """Asserts that the message in a triggered warning matches a regexp.
1122 Basic functioning is similar to assertWarns() with the addition
1123 that only warnings whose messages also match the regular expression
1124 are considered successful matches.
1125
1126 Args:
1127 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001128 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001129 to be found in error message.
1130 callable_obj: Function to be called.
1131 args: Extra args.
1132 kwargs: Extra kwargs.
1133 """
1134 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001135 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001136 if callable_obj is None:
1137 return context
1138 with context:
1139 callable_obj(*args, **kwargs)
1140
Ezio Melottied3a7d22010-12-01 02:32:32 +00001141 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001142 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001143 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001144 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001145 expected_regex = re.compile(expected_regex)
1146 if not expected_regex.search(text):
1147 msg = msg or "Regex didn't match"
1148 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001149 raise self.failureException(msg)
1150
Ezio Melotti8f776302010-12-10 02:32:05 +00001151 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001152 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001153 if isinstance(unexpected_regex, (str, bytes)):
1154 unexpected_regex = re.compile(unexpected_regex)
1155 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001156 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001157 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001158 msg = '%s: %r matches %r in %r' % (msg,
1159 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001160 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001161 text)
1162 raise self.failureException(msg)
1163
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001164
Ezio Melottied3a7d22010-12-01 02:32:32 +00001165 def _deprecate(original_func):
1166 def deprecated_func(*args, **kwargs):
1167 warnings.warn(
1168 'Please use {0} instead.'.format(original_func.__name__),
1169 DeprecationWarning, 2)
1170 return original_func(*args, **kwargs)
1171 return deprecated_func
1172
Ezio Melotti361467e2011-04-03 17:37:58 +03001173 # see #9424
Ezio Melottied3a7d22010-12-01 02:32:32 +00001174 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1175 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1176 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1177 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1178 failUnless = assert_ = _deprecate(assertTrue)
1179 failUnlessRaises = _deprecate(assertRaises)
1180 failIf = _deprecate(assertFalse)
1181 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1182 assertRegexpMatches = _deprecate(assertRegex)
1183
1184
1185
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001186class FunctionTestCase(TestCase):
1187 """A test case that wraps a test function.
1188
1189 This is useful for slipping pre-existing test functions into the
1190 unittest framework. Optionally, set-up and tidy-up functions can be
1191 supplied. As with TestCase, the tidy-up ('tearDown') function will
1192 always be called if the set-up ('setUp') function ran successfully.
1193 """
1194
1195 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1196 super(FunctionTestCase, self).__init__()
1197 self._setUpFunc = setUp
1198 self._tearDownFunc = tearDown
1199 self._testFunc = testFunc
1200 self._description = description
1201
1202 def setUp(self):
1203 if self._setUpFunc is not None:
1204 self._setUpFunc()
1205
1206 def tearDown(self):
1207 if self._tearDownFunc is not None:
1208 self._tearDownFunc()
1209
1210 def runTest(self):
1211 self._testFunc()
1212
1213 def id(self):
1214 return self._testFunc.__name__
1215
1216 def __eq__(self, other):
1217 if not isinstance(other, self.__class__):
1218 return NotImplemented
1219
1220 return self._setUpFunc == other._setUpFunc and \
1221 self._tearDownFunc == other._tearDownFunc and \
1222 self._testFunc == other._testFunc and \
1223 self._description == other._description
1224
1225 def __ne__(self, other):
1226 return not self == other
1227
1228 def __hash__(self):
1229 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1230 self._testFunc, self._description))
1231
1232 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001233 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001234 self._testFunc.__name__)
1235
1236 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001237 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001238 self._testFunc)
1239
1240 def shortDescription(self):
1241 if self._description is not None:
1242 return self._description
1243 doc = self._testFunc.__doc__
1244 return doc and doc.split("\n")[0].strip() or None