blob: 004a9f5d33620450d0281b0866b28613a2fee2e6 [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
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000277 try:
278 testMethod = getattr(self, methodName)
279 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000280 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000281 (self.__class__, methodName))
282 self._testMethodDoc = testMethod.__doc__
283 self._cleanups = []
284
285 # Map types to custom assertEqual functions that will compare
286 # instances of said type in more detail to generate a more useful
287 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000288 self._type_equality_funcs = _TypeEqualityDict(self)
289 self.addTypeEqualityFunc(dict, 'assertDictEqual')
290 self.addTypeEqualityFunc(list, 'assertListEqual')
291 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
292 self.addTypeEqualityFunc(set, 'assertSetEqual')
293 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
294 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000295
296 def addTypeEqualityFunc(self, typeobj, function):
297 """Add a type specific assertEqual style function to compare a type.
298
299 This method is for use by TestCase subclasses that need to register
300 their own type equality functions to provide nicer error messages.
301
302 Args:
303 typeobj: The data type to call this function on when both values
304 are of the same type in assertEqual().
305 function: The callable taking two arguments and an optional
306 msg= argument that raises self.failureException with a
307 useful error message when the two arguments are not equal.
308 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000309 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000310
311 def addCleanup(self, function, *args, **kwargs):
312 """Add a function, with arguments, to be called when the test is
313 completed. Functions added are called on a LIFO basis and are
314 called after tearDown on test failure or success.
315
316 Cleanup items are called even if setUp fails (unlike tearDown)."""
317 self._cleanups.append((function, args, kwargs))
318
319 def setUp(self):
320 "Hook method for setting up the test fixture before exercising it."
321 pass
322
323 def tearDown(self):
324 "Hook method for deconstructing the test fixture after testing it."
325 pass
326
Benjamin Peterson847a4112010-03-14 15:04:17 +0000327 @classmethod
328 def setUpClass(cls):
329 "Hook method for setting up class fixture before running tests in the class."
330
331 @classmethod
332 def tearDownClass(cls):
333 "Hook method for deconstructing the class fixture after running all tests in the class."
334
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000335 def countTestCases(self):
336 return 1
337
338 def defaultTestResult(self):
339 return result.TestResult()
340
341 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000342 """Returns a one-line description of the test, or None if no
343 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000344
Michael Foord34c94622010-02-10 15:51:42 +0000345 The default implementation of this method returns the first line of
346 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000347 """
Michael Foord34c94622010-02-10 15:51:42 +0000348 doc = self._testMethodDoc
349 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000350
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000351
352 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000353 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000354
355 def __eq__(self, other):
356 if type(self) is not type(other):
357 return NotImplemented
358
359 return self._testMethodName == other._testMethodName
360
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000361 def __hash__(self):
362 return hash((type(self), self._testMethodName))
363
364 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000365 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000366
367 def __repr__(self):
368 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000369 (strclass(self.__class__), self._testMethodName)
370
371 def _addSkip(self, result, reason):
372 addSkip = getattr(result, 'addSkip', None)
373 if addSkip is not None:
374 addSkip(self, reason)
375 else:
376 warnings.warn("TestResult has no addSkip method, skips not reported",
377 RuntimeWarning, 2)
378 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000379
Michael Foordb3468f72010-12-19 03:19:47 +0000380 def _executeTestPart(self, function, outcome, isTest=False):
381 try:
382 function()
383 except KeyboardInterrupt:
384 raise
385 except SkipTest as e:
386 outcome.success = False
387 outcome.skipped = str(e)
388 except _UnexpectedSuccess:
389 exc_info = sys.exc_info()
390 outcome.success = False
391 if isTest:
392 outcome.unexpectedSuccess = exc_info
393 else:
394 outcome.errors.append(exc_info)
395 except _ExpectedFailure:
396 outcome.success = False
397 exc_info = sys.exc_info()
398 if isTest:
399 outcome.expectedFailure = exc_info
400 else:
401 outcome.errors.append(exc_info)
402 except self.failureException:
403 outcome.success = False
404 outcome.failures.append(sys.exc_info())
405 exc_info = sys.exc_info()
406 except:
407 outcome.success = False
408 outcome.errors.append(sys.exc_info())
409
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000410 def run(self, result=None):
411 orig_result = result
412 if result is None:
413 result = self.defaultTestResult()
414 startTestRun = getattr(result, 'startTestRun', None)
415 if startTestRun is not None:
416 startTestRun()
417
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000418 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000419
420 testMethod = getattr(self, self._testMethodName)
421 if (getattr(self.__class__, "__unittest_skip__", False) or
422 getattr(testMethod, "__unittest_skip__", False)):
423 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000424 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000425 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
426 or getattr(testMethod, '__unittest_skip_why__', ''))
427 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000428 finally:
429 result.stopTest(self)
430 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000431 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000432 outcome = _Outcome()
433 self._outcomeForDoCleanups = outcome
434
435 self._executeTestPart(self.setUp, outcome)
436 if outcome.success:
437 self._executeTestPart(testMethod, outcome, isTest=True)
438 self._executeTestPart(self.tearDown, outcome)
439
440 self.doCleanups()
441 if outcome.success:
442 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000443 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000444 if outcome.skipped is not None:
445 self._addSkip(result, outcome.skipped)
446 for exc_info in outcome.errors:
447 result.addError(self, exc_info)
448 for exc_info in outcome.failures:
449 result.addFailure(self, exc_info)
450 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000451 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
452 if addUnexpectedSuccess is not None:
453 addUnexpectedSuccess(self)
454 else:
455 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
456 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000457 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000458
Michael Foordb3468f72010-12-19 03:19:47 +0000459 if outcome.expectedFailure is not None:
460 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
461 if addExpectedFailure is not None:
462 addExpectedFailure(self, outcome.expectedFailure)
463 else:
464 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
465 RuntimeWarning)
466 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000468 finally:
469 result.stopTest(self)
470 if orig_result is None:
471 stopTestRun = getattr(result, 'stopTestRun', None)
472 if stopTestRun is not None:
473 stopTestRun()
474
475 def doCleanups(self):
476 """Execute all cleanup functions. Normally called for you after
477 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000478 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000479 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000480 function, args, kwargs = self._cleanups.pop()
481 part = lambda: function(*args, **kwargs)
482 self._executeTestPart(part, outcome)
483
484 # return this for backwards compatibility
485 # even though we no longer us it internally
486 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000487
488 def __call__(self, *args, **kwds):
489 return self.run(*args, **kwds)
490
491 def debug(self):
492 """Run the test without collecting errors in a TestResult"""
493 self.setUp()
494 getattr(self, self._testMethodName)()
495 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000496 while self._cleanups:
497 function, args, kwargs = self._cleanups.pop(-1)
498 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000499
500 def skipTest(self, reason):
501 """Skip this test."""
502 raise SkipTest(reason)
503
504 def fail(self, msg=None):
505 """Fail immediately, with the given message."""
506 raise self.failureException(msg)
507
508 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000509 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000510 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000511 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000512 raise self.failureException(msg)
513
514 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000515 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000516 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000517 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000518 raise self.failureException(msg)
519
520 def _formatMessage(self, msg, standardMsg):
521 """Honour the longMessage attribute when generating failure messages.
522 If longMessage is False this means:
523 * Use only an explicit message if it is provided
524 * Otherwise use the standard message for the assert
525
526 If longMessage is True:
527 * Use the standard message
528 * If an explicit message is provided, plus ' : ' and the explicit message
529 """
530 if not self.longMessage:
531 return msg or standardMsg
532 if msg is None:
533 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000534 try:
535 # don't switch to '{}' formatting in Python 2.X
536 # it changes the way unicode input is handled
537 return '%s : %s' % (standardMsg, msg)
538 except UnicodeDecodeError:
539 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000540
541
542 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
543 """Fail unless an exception of class excClass is thrown
544 by callableObj when invoked with arguments args and keyword
545 arguments kwargs. If a different type of exception is
546 thrown, it will not be caught, and the test case will be
547 deemed to have suffered an error, exactly as for an
548 unexpected exception.
549
550 If called with callableObj omitted or None, will return a
551 context object used like this::
552
Michael Foord1c42b122010-02-05 22:58:21 +0000553 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000554 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000555
556 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000557 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000558 exception after the assertion::
559
560 with self.assertRaises(SomeException) as cm:
561 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000562 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000563 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000564 """
565 context = _AssertRaisesContext(excClass, self, callableObj)
566 if callableObj is None:
567 return context
568 with context:
569 callableObj(*args, **kwargs)
570
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000571 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
572 """Fail unless a warning of class warnClass is triggered
573 by callableObj when invoked with arguments args and keyword
574 arguments kwargs. If a different type of warning is
575 triggered, it will not be handled: depending on the other
576 warning filtering rules in effect, it might be silenced, printed
577 out, or raised as an exception.
578
579 If called with callableObj omitted or None, will return a
580 context object used like this::
581
582 with self.assertWarns(SomeWarning):
583 do_something()
584
585 The context manager keeps a reference to the first matching
586 warning as the 'warning' attribute; similarly, the 'filename'
587 and 'lineno' attributes give you information about the line
588 of Python code from which the warning was triggered.
589 This allows you to inspect the warning after the assertion::
590
591 with self.assertWarns(SomeWarning) as cm:
592 do_something()
593 the_warning = cm.warning
594 self.assertEqual(the_warning.some_attribute, 147)
595 """
596 context = _AssertWarnsContext(expected_warning, self, callable_obj)
597 if callable_obj is None:
598 return context
599 with context:
600 callable_obj(*args, **kwargs)
601
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000602 def _getAssertEqualityFunc(self, first, second):
603 """Get a detailed comparison function for the types of the two args.
604
605 Returns: A callable accepting (first, second, msg=None) that will
606 raise a failure exception if first != second with a useful human
607 readable error message for those types.
608 """
609 #
610 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
611 # and vice versa. I opted for the conservative approach in case
612 # subclasses are not intended to be compared in detail to their super
613 # class instances using a type equality func. This means testing
614 # subtypes won't automagically use the detailed comparison. Callers
615 # should use their type specific assertSpamEqual method to compare
616 # subclasses if the detailed comparison is desired and appropriate.
617 # See the discussion in http://bugs.python.org/issue2578.
618 #
619 if type(first) is type(second):
620 asserter = self._type_equality_funcs.get(type(first))
621 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000622 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000623
624 return self._baseAssertEqual
625
626 def _baseAssertEqual(self, first, second, msg=None):
627 """The default assertEqual implementation, not type specific."""
628 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000629 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000630 msg = self._formatMessage(msg, standardMsg)
631 raise self.failureException(msg)
632
633 def assertEqual(self, first, second, msg=None):
634 """Fail if the two objects are unequal as determined by the '=='
635 operator.
636 """
637 assertion_func = self._getAssertEqualityFunc(first, second)
638 assertion_func(first, second, msg=msg)
639
640 def assertNotEqual(self, first, second, msg=None):
641 """Fail if the two objects are equal as determined by the '=='
642 operator.
643 """
644 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000645 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
646 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000647 raise self.failureException(msg)
648
Michael Foord321d0592010-11-02 13:44:51 +0000649 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000650 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000651 """Fail if the two objects are unequal as determined by their
652 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000653 (default 7) and comparing to zero, or by comparing that the
654 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000655
656 Note that decimal places (from zero) are usually not the same
657 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000658
659 If the two objects compare equal then they will automatically
660 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000661 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000662 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000663 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000664 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000665 if delta is not None and places is not None:
666 raise TypeError("specify delta or places not both")
667
668 if delta is not None:
669 if abs(first - second) <= delta:
670 return
671
672 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
673 safe_repr(second),
674 safe_repr(delta))
675 else:
676 if places is None:
677 places = 7
678
679 if round(abs(second-first), places) == 0:
680 return
681
Benjamin Peterson847a4112010-03-14 15:04:17 +0000682 standardMsg = '%s != %s within %r places' % (safe_repr(first),
683 safe_repr(second),
684 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000685 msg = self._formatMessage(msg, standardMsg)
686 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000687
Michael Foord321d0592010-11-02 13:44:51 +0000688 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000689 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000690 """Fail if the two objects are equal as determined by their
691 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000692 (default 7) and comparing to zero, or by comparing that the
693 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000694
695 Note that decimal places (from zero) are usually not the same
696 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000697
698 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000700 if delta is not None and places is not None:
701 raise TypeError("specify delta or places not both")
702 if delta is not None:
703 if not (first == second) and abs(first - second) > delta:
704 return
705 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
706 safe_repr(second),
707 safe_repr(delta))
708 else:
709 if places is None:
710 places = 7
711 if not (first == second) and round(abs(second-first), places) != 0:
712 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000713 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000714 safe_repr(second),
715 places)
716
717 msg = self._formatMessage(msg, standardMsg)
718 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000719
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000720
Michael Foord085dfd32010-06-05 12:17:02 +0000721 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000722 """An equality assertion for ordered sequences (like lists and tuples).
723
R. David Murrayad13f222010-01-29 22:17:58 +0000724 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000725 which can be indexed, has a length, and has an equality operator.
726
727 Args:
728 seq1: The first sequence to compare.
729 seq2: The second sequence to compare.
730 seq_type: The expected datatype of the sequences, or None if no
731 datatype should be enforced.
732 msg: Optional message to use on failure instead of a list of
733 differences.
734 """
735 if seq_type != None:
736 seq_type_name = seq_type.__name__
737 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000738 raise self.failureException('First sequence is not a %s: %s'
739 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000740 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000741 raise self.failureException('Second sequence is not a %s: %s'
742 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000743 else:
744 seq_type_name = "sequence"
745
746 differing = None
747 try:
748 len1 = len(seq1)
749 except (TypeError, NotImplementedError):
750 differing = 'First %s has no length. Non-sequence?' % (
751 seq_type_name)
752
753 if differing is None:
754 try:
755 len2 = len(seq2)
756 except (TypeError, NotImplementedError):
757 differing = 'Second %s has no length. Non-sequence?' % (
758 seq_type_name)
759
760 if differing is None:
761 if seq1 == seq2:
762 return
763
Benjamin Peterson847a4112010-03-14 15:04:17 +0000764 seq1_repr = safe_repr(seq1)
765 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000766 if len(seq1_repr) > 30:
767 seq1_repr = seq1_repr[:30] + '...'
768 if len(seq2_repr) > 30:
769 seq2_repr = seq2_repr[:30] + '...'
770 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
771 differing = '%ss differ: %s != %s\n' % elements
772
773 for i in range(min(len1, len2)):
774 try:
775 item1 = seq1[i]
776 except (TypeError, IndexError, NotImplementedError):
777 differing += ('\nUnable to index element %d of first %s\n' %
778 (i, seq_type_name))
779 break
780
781 try:
782 item2 = seq2[i]
783 except (TypeError, IndexError, NotImplementedError):
784 differing += ('\nUnable to index element %d of second %s\n' %
785 (i, seq_type_name))
786 break
787
788 if item1 != item2:
789 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
790 (i, item1, item2))
791 break
792 else:
793 if (len1 == len2 and seq_type is None and
794 type(seq1) != type(seq2)):
795 # The sequences are the same, but have differing types.
796 return
797
798 if len1 > len2:
799 differing += ('\nFirst %s contains %d additional '
800 'elements.\n' % (seq_type_name, len1 - len2))
801 try:
802 differing += ('First extra element %d:\n%s\n' %
803 (len2, seq1[len2]))
804 except (TypeError, IndexError, NotImplementedError):
805 differing += ('Unable to index element %d '
806 'of first %s\n' % (len2, seq_type_name))
807 elif len1 < len2:
808 differing += ('\nSecond %s contains %d additional '
809 'elements.\n' % (seq_type_name, len2 - len1))
810 try:
811 differing += ('First extra element %d:\n%s\n' %
812 (len1, seq2[len1]))
813 except (TypeError, IndexError, NotImplementedError):
814 differing += ('Unable to index element %d '
815 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000816 standardMsg = differing
817 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000818 difflib.ndiff(pprint.pformat(seq1).splitlines(),
819 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000820
821 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000822 msg = self._formatMessage(msg, standardMsg)
823 self.fail(msg)
824
Michael Foord085dfd32010-06-05 12:17:02 +0000825 def _truncateMessage(self, message, diff):
826 max_diff = self.maxDiff
827 if max_diff is None or len(diff) <= max_diff:
828 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000829 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000830
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000831 def assertListEqual(self, list1, list2, msg=None):
832 """A list-specific equality assertion.
833
834 Args:
835 list1: The first list to compare.
836 list2: The second list to compare.
837 msg: Optional message to use on failure instead of a list of
838 differences.
839
840 """
841 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
842
843 def assertTupleEqual(self, tuple1, tuple2, msg=None):
844 """A tuple-specific equality assertion.
845
846 Args:
847 tuple1: The first tuple to compare.
848 tuple2: The second tuple to compare.
849 msg: Optional message to use on failure instead of a list of
850 differences.
851 """
852 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
853
854 def assertSetEqual(self, set1, set2, msg=None):
855 """A set-specific equality assertion.
856
857 Args:
858 set1: The first set to compare.
859 set2: The second set to compare.
860 msg: Optional message to use on failure instead of a list of
861 differences.
862
Michael Foord91c9da32010-03-20 17:21:27 +0000863 assertSetEqual uses ducktyping to support different types of sets, and
864 is optimized for sets specifically (parameters must support a
865 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000866 """
867 try:
868 difference1 = set1.difference(set2)
869 except TypeError as e:
870 self.fail('invalid type when attempting set difference: %s' % e)
871 except AttributeError as e:
872 self.fail('first argument does not support set difference: %s' % e)
873
874 try:
875 difference2 = set2.difference(set1)
876 except TypeError as e:
877 self.fail('invalid type when attempting set difference: %s' % e)
878 except AttributeError as e:
879 self.fail('second argument does not support set difference: %s' % e)
880
881 if not (difference1 or difference2):
882 return
883
884 lines = []
885 if difference1:
886 lines.append('Items in the first set but not the second:')
887 for item in difference1:
888 lines.append(repr(item))
889 if difference2:
890 lines.append('Items in the second set but not the first:')
891 for item in difference2:
892 lines.append(repr(item))
893
894 standardMsg = '\n'.join(lines)
895 self.fail(self._formatMessage(msg, standardMsg))
896
897 def assertIn(self, member, container, msg=None):
898 """Just like self.assertTrue(a in b), but with a nicer default message."""
899 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000900 standardMsg = '%s not found in %s' % (safe_repr(member),
901 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000902 self.fail(self._formatMessage(msg, standardMsg))
903
904 def assertNotIn(self, member, container, msg=None):
905 """Just like self.assertTrue(a not in b), but with a nicer default message."""
906 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000907 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
908 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000909 self.fail(self._formatMessage(msg, standardMsg))
910
911 def assertIs(self, expr1, expr2, msg=None):
912 """Just like self.assertTrue(a is b), but with a nicer default message."""
913 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000914 standardMsg = '%s is not %s' % (safe_repr(expr1),
915 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000916 self.fail(self._formatMessage(msg, standardMsg))
917
918 def assertIsNot(self, expr1, expr2, msg=None):
919 """Just like self.assertTrue(a is not b), but with a nicer default message."""
920 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000921 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000922 self.fail(self._formatMessage(msg, standardMsg))
923
924 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000925 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
926 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000927
928 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000929 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000930 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000931 pprint.pformat(d1).splitlines(),
932 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000933 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000934 self.fail(self._formatMessage(msg, standardMsg))
935
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000936 def assertDictContainsSubset(self, subset, dictionary, msg=None):
937 """Checks whether dictionary is a superset of subset."""
Raymond Hettinger8ebe27f2010-12-21 19:24:26 +0000938 warnings.warn('assertDictContainsSubset is deprecated',
939 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000940 missing = []
941 mismatched = []
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000942 for key, value in subset.items():
943 if key not in dictionary:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000944 missing.append(key)
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000945 elif value != dictionary[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000946 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000947 (safe_repr(key), safe_repr(value),
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000948 safe_repr(dictionary[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000949
950 if not (missing or mismatched):
951 return
952
953 standardMsg = ''
954 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000955 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
956 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000957 if mismatched:
958 if standardMsg:
959 standardMsg += '; '
960 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
961
962 self.fail(self._formatMessage(msg, standardMsg))
963
964 def assertSameElements(self, expected_seq, actual_seq, msg=None):
965 """An unordered sequence specific comparison.
966
967 Raises with an error message listing which elements of expected_seq
968 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000969
970 Duplicate elements are ignored when comparing *expected_seq* and
971 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
972 set(actual))`` but it works with sequences of unhashable objects as
973 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000974 """
Michael Foord91c9da32010-03-20 17:21:27 +0000975 warnings.warn('assertSameElements is deprecated',
976 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000977 try:
978 expected = set(expected_seq)
979 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000980 missing = sorted(expected.difference(actual))
981 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000982 except TypeError:
983 # Fall back to slower list-compare if any of the objects are
984 # not hashable.
985 expected = list(expected_seq)
986 actual = list(actual_seq)
987 try:
988 expected.sort()
989 actual.sort()
990 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000991 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000992 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000993 else:
994 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000995 errors = []
996 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000997 errors.append('Expected, but missing:\n %s' %
998 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000999 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001000 errors.append('Unexpected, but present:\n %s' %
1001 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001002 if errors:
1003 standardMsg = '\n'.join(errors)
1004 self.fail(self._formatMessage(msg, standardMsg))
1005
Michael Foord8442a602010-03-20 16:58:04 +00001006
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001007 def assertCountEqual(self, first, second, msg=None):
1008 """An unordered sequence comparison asserting that the same elements,
1009 regardless of order. If the same element occurs more than once,
1010 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +00001011
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001012 self.assertEqual(Counter(list(first)),
1013 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +00001014
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001015 Example:
Michael Foord8442a602010-03-20 16:58:04 +00001016 - [0, 1, 1] and [1, 0, 1] compare equal.
1017 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001018
Michael Foord8442a602010-03-20 16:58:04 +00001019 """
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001020 actual_seq, expected_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +00001021 try:
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001022 actual = collections.Counter(actual_seq)
1023 expected = collections.Counter(expected_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001024 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001025 # Handle case with unhashable elements
Raymond Hettinger9d668da2010-12-24 11:20:30 +00001026 differences = _count_diff_all_purpose(actual_seq, expected_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001027 else:
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001028 if actual == expected:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001029 return
Raymond Hettinger9d668da2010-12-24 11:20:30 +00001030 differences = _count_diff_hashable(actual_seq, expected_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001031
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001032 if differences:
1033 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001034 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001035 diffMsg = '\n'.join(lines)
1036 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1037 msg = self._formatMessage(msg, standardMsg)
1038 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001039
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001040 def assertMultiLineEqual(self, first, second, msg=None):
1041 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001042 self.assertIsInstance(first, str, 'First argument is not a string')
1043 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001044
1045 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001046 firstlines = first.splitlines(True)
1047 secondlines = second.splitlines(True)
1048 if len(firstlines) == 1 and first.strip('\r\n') == first:
1049 firstlines = [first + '\n']
1050 secondlines = [second + '\n']
1051 standardMsg = '%s != %s' % (safe_repr(first, True),
1052 safe_repr(second, True))
1053 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001054 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001055 self.fail(self._formatMessage(msg, standardMsg))
1056
1057 def assertLess(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 %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001061 self.fail(self._formatMessage(msg, standardMsg))
1062
1063 def assertLessEqual(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 less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001067 self.fail(self._formatMessage(msg, standardMsg))
1068
1069 def assertGreater(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 %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001073 self.fail(self._formatMessage(msg, standardMsg))
1074
1075 def assertGreaterEqual(self, a, b, msg=None):
1076 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1077 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001078 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001079 self.fail(self._formatMessage(msg, standardMsg))
1080
1081 def assertIsNone(self, obj, msg=None):
1082 """Same as self.assertTrue(obj is None), with a nicer default message."""
1083 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001084 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001085 self.fail(self._formatMessage(msg, standardMsg))
1086
1087 def assertIsNotNone(self, obj, msg=None):
1088 """Included for symmetry with assertIsNone."""
1089 if obj is None:
1090 standardMsg = 'unexpectedly None'
1091 self.fail(self._formatMessage(msg, standardMsg))
1092
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001093 def assertIsInstance(self, obj, cls, msg=None):
1094 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1095 default message."""
1096 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001097 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001098 self.fail(self._formatMessage(msg, standardMsg))
1099
1100 def assertNotIsInstance(self, obj, cls, msg=None):
1101 """Included for symmetry with assertIsInstance."""
1102 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001103 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001104 self.fail(self._formatMessage(msg, standardMsg))
1105
Ezio Melottied3a7d22010-12-01 02:32:32 +00001106 def assertRaisesRegex(self, expected_exception, expected_regex,
1107 callable_obj=None, *args, **kwargs):
1108 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001109
1110 Args:
1111 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001112 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001113 to be found in error message.
1114 callable_obj: Function to be called.
1115 args: Extra args.
1116 kwargs: Extra kwargs.
1117 """
1118 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001119 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001120 if callable_obj is None:
1121 return context
1122 with context:
1123 callable_obj(*args, **kwargs)
1124
Ezio Melottied3a7d22010-12-01 02:32:32 +00001125 def assertWarnsRegex(self, expected_warning, expected_regex,
1126 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001127 """Asserts that the message in a triggered warning matches a regexp.
1128 Basic functioning is similar to assertWarns() with the addition
1129 that only warnings whose messages also match the regular expression
1130 are considered successful matches.
1131
1132 Args:
1133 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001134 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001135 to be found in error message.
1136 callable_obj: Function to be called.
1137 args: Extra args.
1138 kwargs: Extra kwargs.
1139 """
1140 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001141 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001142 if callable_obj is None:
1143 return context
1144 with context:
1145 callable_obj(*args, **kwargs)
1146
Ezio Melottied3a7d22010-12-01 02:32:32 +00001147 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001148 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001149 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001150 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001151 expected_regex = re.compile(expected_regex)
1152 if not expected_regex.search(text):
1153 msg = msg or "Regex didn't match"
1154 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001155 raise self.failureException(msg)
1156
Ezio Melotti8f776302010-12-10 02:32:05 +00001157 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001158 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001159 if isinstance(unexpected_regex, (str, bytes)):
1160 unexpected_regex = re.compile(unexpected_regex)
1161 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001162 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001163 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001164 msg = '%s: %r matches %r in %r' % (msg,
1165 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001166 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001167 text)
1168 raise self.failureException(msg)
1169
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001170
Ezio Melottied3a7d22010-12-01 02:32:32 +00001171 def _deprecate(original_func):
1172 def deprecated_func(*args, **kwargs):
1173 warnings.warn(
1174 'Please use {0} instead.'.format(original_func.__name__),
1175 DeprecationWarning, 2)
1176 return original_func(*args, **kwargs)
1177 return deprecated_func
1178
1179 # The fail* methods can be removed in 3.3, the 5 assert* methods will
1180 # have to stay around for a few more versions. See #9424.
1181 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1182 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1183 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1184 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1185 failUnless = assert_ = _deprecate(assertTrue)
1186 failUnlessRaises = _deprecate(assertRaises)
1187 failIf = _deprecate(assertFalse)
1188 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1189 assertRegexpMatches = _deprecate(assertRegex)
1190
1191
1192
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001193class FunctionTestCase(TestCase):
1194 """A test case that wraps a test function.
1195
1196 This is useful for slipping pre-existing test functions into the
1197 unittest framework. Optionally, set-up and tidy-up functions can be
1198 supplied. As with TestCase, the tidy-up ('tearDown') function will
1199 always be called if the set-up ('setUp') function ran successfully.
1200 """
1201
1202 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1203 super(FunctionTestCase, self).__init__()
1204 self._setUpFunc = setUp
1205 self._tearDownFunc = tearDown
1206 self._testFunc = testFunc
1207 self._description = description
1208
1209 def setUp(self):
1210 if self._setUpFunc is not None:
1211 self._setUpFunc()
1212
1213 def tearDown(self):
1214 if self._tearDownFunc is not None:
1215 self._tearDownFunc()
1216
1217 def runTest(self):
1218 self._testFunc()
1219
1220 def id(self):
1221 return self._testFunc.__name__
1222
1223 def __eq__(self, other):
1224 if not isinstance(other, self.__class__):
1225 return NotImplemented
1226
1227 return self._setUpFunc == other._setUpFunc and \
1228 self._tearDownFunc == other._tearDownFunc and \
1229 self._testFunc == other._testFunc and \
1230 self._description == other._description
1231
1232 def __ne__(self, other):
1233 return not self == other
1234
1235 def __hash__(self):
1236 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1237 self._testFunc, self._description))
1238
1239 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001240 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001241 self._testFunc.__name__)
1242
1243 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001244 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001245 self._testFunc)
1246
1247 def shortDescription(self):
1248 if self._description is not None:
1249 return self._description
1250 doc = self._testFunc.__doc__
1251 return doc and doc.split("\n")[0].strip() or None