blob: 235af82820442f6f1e6efa4eb6634819d499dc2a [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 Hettingerd65a9012010-12-23 21:54:02 +00001007 def assertCountEqual(self, actual, expected, msg=None):
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001008 """An unordered sequence specific comparison. It asserts that
Raymond Hettingerc44befb2010-12-24 00:58:34 +00001009 actual and expected have the same element counts.
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001010 Equivalent to::
Michael Foord8442a602010-03-20 16:58:04 +00001011
Raymond Hettingerc44befb2010-12-24 00:58:34 +00001012 self.assertEqual(Counter(list(actual)),
1013 Counter(list(expected)))
Michael Foord8442a602010-03-20 16:58:04 +00001014
1015 Asserts that each element has the same count in both sequences.
1016 Example:
1017 - [0, 1, 1] and [1, 0, 1] compare equal.
1018 - [0, 0, 1] and [0, 1] compare unequal.
1019 """
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001020 actual_seq, expected_seq = list(actual), list(expected)
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 Hettinger93e233d2010-12-24 10:02:22 +00001026 differences = _count_diff_all_purpose(expected_seq, actual_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 Hettinger93e233d2010-12-24 10:02:22 +00001030 differences = _count_diff_hashable(expected_seq, actual_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'
1034 lines = []
1035 for act, exp, elem in differences:
1036 line = 'Expected %d, got %d: %r' % (exp, act, elem)
1037 lines.append(line)
1038 diffMsg = '\n'.join(lines)
1039 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1040 msg = self._formatMessage(msg, standardMsg)
1041 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001042
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001043 def assertMultiLineEqual(self, first, second, msg=None):
1044 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001045 self.assertIsInstance(first, str, 'First argument is not a string')
1046 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001047
1048 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001049 firstlines = first.splitlines(True)
1050 secondlines = second.splitlines(True)
1051 if len(firstlines) == 1 and first.strip('\r\n') == first:
1052 firstlines = [first + '\n']
1053 secondlines = [second + '\n']
1054 standardMsg = '%s != %s' % (safe_repr(first, True),
1055 safe_repr(second, True))
1056 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001057 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001058 self.fail(self._formatMessage(msg, standardMsg))
1059
1060 def assertLess(self, a, b, msg=None):
1061 """Just like self.assertTrue(a < b), but with a nicer default message."""
1062 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001063 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001064 self.fail(self._formatMessage(msg, standardMsg))
1065
1066 def assertLessEqual(self, a, b, msg=None):
1067 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1068 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001069 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001070 self.fail(self._formatMessage(msg, standardMsg))
1071
1072 def assertGreater(self, a, b, msg=None):
1073 """Just like self.assertTrue(a > b), but with a nicer default message."""
1074 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001075 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001076 self.fail(self._formatMessage(msg, standardMsg))
1077
1078 def assertGreaterEqual(self, a, b, msg=None):
1079 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1080 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001081 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001082 self.fail(self._formatMessage(msg, standardMsg))
1083
1084 def assertIsNone(self, obj, msg=None):
1085 """Same as self.assertTrue(obj is None), with a nicer default message."""
1086 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001087 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001088 self.fail(self._formatMessage(msg, standardMsg))
1089
1090 def assertIsNotNone(self, obj, msg=None):
1091 """Included for symmetry with assertIsNone."""
1092 if obj is None:
1093 standardMsg = 'unexpectedly None'
1094 self.fail(self._formatMessage(msg, standardMsg))
1095
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001096 def assertIsInstance(self, obj, cls, msg=None):
1097 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1098 default message."""
1099 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001100 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001101 self.fail(self._formatMessage(msg, standardMsg))
1102
1103 def assertNotIsInstance(self, obj, cls, msg=None):
1104 """Included for symmetry with assertIsInstance."""
1105 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001106 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001107 self.fail(self._formatMessage(msg, standardMsg))
1108
Ezio Melottied3a7d22010-12-01 02:32:32 +00001109 def assertRaisesRegex(self, expected_exception, expected_regex,
1110 callable_obj=None, *args, **kwargs):
1111 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001112
1113 Args:
1114 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001115 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001116 to be found in error message.
1117 callable_obj: Function to be called.
1118 args: Extra args.
1119 kwargs: Extra kwargs.
1120 """
1121 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001122 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001123 if callable_obj is None:
1124 return context
1125 with context:
1126 callable_obj(*args, **kwargs)
1127
Ezio Melottied3a7d22010-12-01 02:32:32 +00001128 def assertWarnsRegex(self, expected_warning, expected_regex,
1129 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001130 """Asserts that the message in a triggered warning matches a regexp.
1131 Basic functioning is similar to assertWarns() with the addition
1132 that only warnings whose messages also match the regular expression
1133 are considered successful matches.
1134
1135 Args:
1136 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001137 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001138 to be found in error message.
1139 callable_obj: Function to be called.
1140 args: Extra args.
1141 kwargs: Extra kwargs.
1142 """
1143 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001144 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001145 if callable_obj is None:
1146 return context
1147 with context:
1148 callable_obj(*args, **kwargs)
1149
Ezio Melottied3a7d22010-12-01 02:32:32 +00001150 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001151 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001152 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001153 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001154 expected_regex = re.compile(expected_regex)
1155 if not expected_regex.search(text):
1156 msg = msg or "Regex didn't match"
1157 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001158 raise self.failureException(msg)
1159
Ezio Melotti8f776302010-12-10 02:32:05 +00001160 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001161 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001162 if isinstance(unexpected_regex, (str, bytes)):
1163 unexpected_regex = re.compile(unexpected_regex)
1164 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001165 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001166 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001167 msg = '%s: %r matches %r in %r' % (msg,
1168 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001169 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001170 text)
1171 raise self.failureException(msg)
1172
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001173
Ezio Melottied3a7d22010-12-01 02:32:32 +00001174 def _deprecate(original_func):
1175 def deprecated_func(*args, **kwargs):
1176 warnings.warn(
1177 'Please use {0} instead.'.format(original_func.__name__),
1178 DeprecationWarning, 2)
1179 return original_func(*args, **kwargs)
1180 return deprecated_func
1181
1182 # The fail* methods can be removed in 3.3, the 5 assert* methods will
1183 # have to stay around for a few more versions. See #9424.
1184 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1185 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1186 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1187 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1188 failUnless = assert_ = _deprecate(assertTrue)
1189 failUnlessRaises = _deprecate(assertRaises)
1190 failIf = _deprecate(assertFalse)
1191 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1192 assertRegexpMatches = _deprecate(assertRegex)
1193
1194
1195
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001196class FunctionTestCase(TestCase):
1197 """A test case that wraps a test function.
1198
1199 This is useful for slipping pre-existing test functions into the
1200 unittest framework. Optionally, set-up and tidy-up functions can be
1201 supplied. As with TestCase, the tidy-up ('tearDown') function will
1202 always be called if the set-up ('setUp') function ran successfully.
1203 """
1204
1205 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1206 super(FunctionTestCase, self).__init__()
1207 self._setUpFunc = setUp
1208 self._tearDownFunc = tearDown
1209 self._testFunc = testFunc
1210 self._description = description
1211
1212 def setUp(self):
1213 if self._setUpFunc is not None:
1214 self._setUpFunc()
1215
1216 def tearDown(self):
1217 if self._tearDownFunc is not None:
1218 self._tearDownFunc()
1219
1220 def runTest(self):
1221 self._testFunc()
1222
1223 def id(self):
1224 return self._testFunc.__name__
1225
1226 def __eq__(self, other):
1227 if not isinstance(other, self.__class__):
1228 return NotImplemented
1229
1230 return self._setUpFunc == other._setUpFunc and \
1231 self._tearDownFunc == other._tearDownFunc and \
1232 self._testFunc == other._testFunc and \
1233 self._description == other._description
1234
1235 def __ne__(self, other):
1236 return not self == other
1237
1238 def __hash__(self):
1239 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1240 self._testFunc, self._description))
1241
1242 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001243 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001244 self._testFunc.__name__)
1245
1246 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001247 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001248 self._testFunc)
1249
1250 def shortDescription(self):
1251 if self._description is not None:
1252 return self._description
1253 doc = self._testFunc.__doc__
1254 return doc and doc.split("\n")[0].strip() or None