blob: ad5fe6158968677fd5b707f807d2fef4f7c7ffdf [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,
13 unorderable_list_difference)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000014
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000015__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000016
Michael Foord9dad32e2010-06-05 13:49:56 +000017
18DIFF_OMITTED = ('\nDiff is %s characters long. '
19 'Set self.maxDiff to None to see it.')
20
Benjamin Petersonbed7d042009-07-19 21:01:52 +000021class SkipTest(Exception):
22 """
23 Raise this exception in a test to skip it.
24
25 Usually you can use TestResult.skip() or one of the skipping decorators
26 instead of raising this directly.
27 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000028
29class _ExpectedFailure(Exception):
30 """
31 Raise this when a test is expected to fail.
32
33 This is an implementation detail.
34 """
35
36 def __init__(self, exc_info):
37 super(_ExpectedFailure, self).__init__()
38 self.exc_info = exc_info
39
40class _UnexpectedSuccess(Exception):
41 """
42 The test was supposed to fail, but it didn't!
43 """
Michael Foordb3468f72010-12-19 03:19:47 +000044
45
46class _Outcome(object):
47 def __init__(self):
48 self.success = True
49 self.skipped = None
50 self.unexpectedSuccess = None
51 self.expectedFailure = None
52 self.errors = []
53 self.failures = []
54
Benjamin Petersonbed7d042009-07-19 21:01:52 +000055
56def _id(obj):
57 return obj
58
59def skip(reason):
60 """
61 Unconditionally skip a test.
62 """
63 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000064 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
65 @functools.wraps(test_item)
66 def skip_wrapper(*args, **kwargs):
67 raise SkipTest(reason)
68 test_item = skip_wrapper
69
70 test_item.__unittest_skip__ = True
71 test_item.__unittest_skip_why__ = reason
72 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000073 return decorator
74
75def skipIf(condition, reason):
76 """
77 Skip a test if the condition is true.
78 """
79 if condition:
80 return skip(reason)
81 return _id
82
83def skipUnless(condition, reason):
84 """
85 Skip a test unless the condition is true.
86 """
87 if not condition:
88 return skip(reason)
89 return _id
90
91
92def expectedFailure(func):
93 @functools.wraps(func)
94 def wrapper(*args, **kwargs):
95 try:
96 func(*args, **kwargs)
97 except Exception:
98 raise _ExpectedFailure(sys.exc_info())
99 raise _UnexpectedSuccess
100 return wrapper
101
102
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000103class _AssertRaisesBaseContext(object):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000104
105 def __init__(self, expected, test_case, callable_obj=None,
Ezio Melottied3a7d22010-12-01 02:32:32 +0000106 expected_regex=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000107 self.expected = expected
108 self.failureException = test_case.failureException
109 if callable_obj is not None:
110 try:
111 self.obj_name = callable_obj.__name__
112 except AttributeError:
113 self.obj_name = str(callable_obj)
114 else:
115 self.obj_name = None
Ezio Melottied3a7d22010-12-01 02:32:32 +0000116 if isinstance(expected_regex, (bytes, str)):
117 expected_regex = re.compile(expected_regex)
118 self.expected_regex = expected_regex
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000119
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000120
121class _AssertRaisesContext(_AssertRaisesBaseContext):
122 """A context manager used to implement TestCase.assertRaises* methods."""
123
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000124 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000125 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000126
127 def __exit__(self, exc_type, exc_value, tb):
128 if exc_type is None:
129 try:
130 exc_name = self.expected.__name__
131 except AttributeError:
132 exc_name = str(self.expected)
133 if self.obj_name:
134 raise self.failureException("{0} not raised by {1}"
135 .format(exc_name, self.obj_name))
136 else:
137 raise self.failureException("{0} not raised"
138 .format(exc_name))
139 if not issubclass(exc_type, self.expected):
140 # let unexpected exceptions pass through
141 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000142 # store exception, without traceback, for later retrieval
143 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000144 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000145 return True
146
Ezio Melottied3a7d22010-12-01 02:32:32 +0000147 expected_regex = self.expected_regex
148 if not expected_regex.search(str(exc_value)):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000149 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000150 (expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000151 return True
152
153
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000154class _AssertWarnsContext(_AssertRaisesBaseContext):
155 """A context manager used to implement TestCase.assertWarns* methods."""
156
157 def __enter__(self):
158 # The __warningregistry__'s need to be in a pristine state for tests
159 # to work properly.
160 for v in sys.modules.values():
161 if getattr(v, '__warningregistry__', None):
162 v.__warningregistry__ = {}
163 self.warnings_manager = warnings.catch_warnings(record=True)
164 self.warnings = self.warnings_manager.__enter__()
165 warnings.simplefilter("always", self.expected)
166 return self
167
168 def __exit__(self, exc_type, exc_value, tb):
169 self.warnings_manager.__exit__(exc_type, exc_value, tb)
170 if exc_type is not None:
171 # let unexpected exceptions pass through
172 return
173 try:
174 exc_name = self.expected.__name__
175 except AttributeError:
176 exc_name = str(self.expected)
177 first_matching = None
178 for m in self.warnings:
179 w = m.message
180 if not isinstance(w, self.expected):
181 continue
182 if first_matching is None:
183 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000184 if (self.expected_regex is not None and
185 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000186 continue
187 # store warning for later retrieval
188 self.warning = w
189 self.filename = m.filename
190 self.lineno = m.lineno
191 return
192 # Now we simply try to choose a helpful failure message
193 if first_matching is not None:
194 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000195 (self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000196 if self.obj_name:
197 raise self.failureException("{0} not triggered by {1}"
198 .format(exc_name, self.obj_name))
199 else:
200 raise self.failureException("{0} not triggered"
201 .format(exc_name))
202
203
Michael Foord8ca6d982010-11-20 15:34:26 +0000204class _TypeEqualityDict(object):
205
206 def __init__(self, testcase):
207 self.testcase = testcase
208 self._store = {}
209
210 def __setitem__(self, key, value):
211 self._store[key] = value
212
213 def __getitem__(self, key):
214 value = self._store[key]
215 if isinstance(value, str):
216 return getattr(self.testcase, value)
217 return value
218
219 def get(self, key, default=None):
220 if key in self._store:
221 return self[key]
222 return default
223
224
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000225class TestCase(object):
226 """A class whose instances are single test cases.
227
228 By default, the test code itself should be placed in a method named
229 'runTest'.
230
231 If the fixture may be used for many test cases, create as
232 many test methods as are needed. When instantiating such a TestCase
233 subclass, specify in the constructor arguments the name of the test method
234 that the instance is to execute.
235
236 Test authors should subclass TestCase for their own tests. Construction
237 and deconstruction of the test's environment ('fixture') can be
238 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
239
240 If it is necessary to override the __init__ method, the base class
241 __init__ method must always be called. It is important that subclasses
242 should not change the signature of their __init__ method, since instances
243 of the classes are instantiated automatically by parts of the framework
244 in order to be run.
245 """
246
247 # This attribute determines which exception will be raised when
248 # the instance's assertion methods fail; test methods raising this
249 # exception will be deemed to have 'failed' rather than 'errored'
250
251 failureException = AssertionError
252
253 # This attribute determines whether long messages (including repr of
254 # objects used in assert methods) will be printed on failure in *addition*
255 # to any explicit message passed.
256
Michael Foord5074df62010-12-03 00:53:09 +0000257 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000258
Michael Foordc41d1412010-06-10 16:17:07 +0000259 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000260 # by assert methods using difflib. It is looked up as an instance attribute
261 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000262
Michael Foord085dfd32010-06-05 12:17:02 +0000263 maxDiff = 80*8
264
Benjamin Peterson847a4112010-03-14 15:04:17 +0000265 # Attribute used by TestSuite for classSetUp
266
267 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000268
269 def __init__(self, methodName='runTest'):
270 """Create an instance of the class that will use the named test
271 method when executed. Raises a ValueError if the instance does
272 not have a method with the specified name.
273 """
274 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000275 self._outcomeForDoCleanups = None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000276 try:
277 testMethod = getattr(self, methodName)
278 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000279 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000280 (self.__class__, methodName))
281 self._testMethodDoc = testMethod.__doc__
282 self._cleanups = []
283
284 # Map types to custom assertEqual functions that will compare
285 # instances of said type in more detail to generate a more useful
286 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000287 self._type_equality_funcs = _TypeEqualityDict(self)
288 self.addTypeEqualityFunc(dict, 'assertDictEqual')
289 self.addTypeEqualityFunc(list, 'assertListEqual')
290 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
291 self.addTypeEqualityFunc(set, 'assertSetEqual')
292 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
293 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000294
295 def addTypeEqualityFunc(self, typeobj, function):
296 """Add a type specific assertEqual style function to compare a type.
297
298 This method is for use by TestCase subclasses that need to register
299 their own type equality functions to provide nicer error messages.
300
301 Args:
302 typeobj: The data type to call this function on when both values
303 are of the same type in assertEqual().
304 function: The callable taking two arguments and an optional
305 msg= argument that raises self.failureException with a
306 useful error message when the two arguments are not equal.
307 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000308 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000309
310 def addCleanup(self, function, *args, **kwargs):
311 """Add a function, with arguments, to be called when the test is
312 completed. Functions added are called on a LIFO basis and are
313 called after tearDown on test failure or success.
314
315 Cleanup items are called even if setUp fails (unlike tearDown)."""
316 self._cleanups.append((function, args, kwargs))
317
318 def setUp(self):
319 "Hook method for setting up the test fixture before exercising it."
320 pass
321
322 def tearDown(self):
323 "Hook method for deconstructing the test fixture after testing it."
324 pass
325
Benjamin Peterson847a4112010-03-14 15:04:17 +0000326 @classmethod
327 def setUpClass(cls):
328 "Hook method for setting up class fixture before running tests in the class."
329
330 @classmethod
331 def tearDownClass(cls):
332 "Hook method for deconstructing the class fixture after running all tests in the class."
333
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000334 def countTestCases(self):
335 return 1
336
337 def defaultTestResult(self):
338 return result.TestResult()
339
340 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000341 """Returns a one-line description of the test, or None if no
342 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000343
Michael Foord34c94622010-02-10 15:51:42 +0000344 The default implementation of this method returns the first line of
345 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000346 """
Michael Foord34c94622010-02-10 15:51:42 +0000347 doc = self._testMethodDoc
348 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000349
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000350
351 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000352 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000353
354 def __eq__(self, other):
355 if type(self) is not type(other):
356 return NotImplemented
357
358 return self._testMethodName == other._testMethodName
359
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000360 def __hash__(self):
361 return hash((type(self), self._testMethodName))
362
363 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000364 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000365
366 def __repr__(self):
367 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000368 (strclass(self.__class__), self._testMethodName)
369
370 def _addSkip(self, result, reason):
371 addSkip = getattr(result, 'addSkip', None)
372 if addSkip is not None:
373 addSkip(self, reason)
374 else:
375 warnings.warn("TestResult has no addSkip method, skips not reported",
376 RuntimeWarning, 2)
377 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000378
Michael Foordb3468f72010-12-19 03:19:47 +0000379 def _executeTestPart(self, function, outcome, isTest=False):
380 try:
381 function()
382 except KeyboardInterrupt:
383 raise
384 except SkipTest as e:
385 outcome.success = False
386 outcome.skipped = str(e)
387 except _UnexpectedSuccess:
388 exc_info = sys.exc_info()
389 outcome.success = False
390 if isTest:
391 outcome.unexpectedSuccess = exc_info
392 else:
393 outcome.errors.append(exc_info)
394 except _ExpectedFailure:
395 outcome.success = False
396 exc_info = sys.exc_info()
397 if isTest:
398 outcome.expectedFailure = exc_info
399 else:
400 outcome.errors.append(exc_info)
401 except self.failureException:
402 outcome.success = False
403 outcome.failures.append(sys.exc_info())
404 exc_info = sys.exc_info()
405 except:
406 outcome.success = False
407 outcome.errors.append(sys.exc_info())
408
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000409 def run(self, result=None):
410 orig_result = result
411 if result is None:
412 result = self.defaultTestResult()
413 startTestRun = getattr(result, 'startTestRun', None)
414 if startTestRun is not None:
415 startTestRun()
416
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000417 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000418
419 testMethod = getattr(self, self._testMethodName)
420 if (getattr(self.__class__, "__unittest_skip__", False) or
421 getattr(testMethod, "__unittest_skip__", False)):
422 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000423 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000424 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
425 or getattr(testMethod, '__unittest_skip_why__', ''))
426 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000427 finally:
428 result.stopTest(self)
429 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000430 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000431 outcome = _Outcome()
432 self._outcomeForDoCleanups = outcome
433
434 self._executeTestPart(self.setUp, outcome)
435 if outcome.success:
436 self._executeTestPart(testMethod, outcome, isTest=True)
437 self._executeTestPart(self.tearDown, outcome)
438
439 self.doCleanups()
440 if outcome.success:
441 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000442 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000443 if outcome.skipped is not None:
444 self._addSkip(result, outcome.skipped)
445 for exc_info in outcome.errors:
446 result.addError(self, exc_info)
447 for exc_info in outcome.failures:
448 result.addFailure(self, exc_info)
449 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000450 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
451 if addUnexpectedSuccess is not None:
452 addUnexpectedSuccess(self)
453 else:
454 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
455 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000456 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000457
Michael Foordb3468f72010-12-19 03:19:47 +0000458 if outcome.expectedFailure is not None:
459 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
460 if addExpectedFailure is not None:
461 addExpectedFailure(self, outcome.expectedFailure)
462 else:
463 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
464 RuntimeWarning)
465 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000466
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467 finally:
468 result.stopTest(self)
469 if orig_result is None:
470 stopTestRun = getattr(result, 'stopTestRun', None)
471 if stopTestRun is not None:
472 stopTestRun()
473
474 def doCleanups(self):
475 """Execute all cleanup functions. Normally called for you after
476 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000477 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000478 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000479 function, args, kwargs = self._cleanups.pop()
480 part = lambda: function(*args, **kwargs)
481 self._executeTestPart(part, outcome)
482
483 # return this for backwards compatibility
484 # even though we no longer us it internally
485 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000486
487 def __call__(self, *args, **kwds):
488 return self.run(*args, **kwds)
489
490 def debug(self):
491 """Run the test without collecting errors in a TestResult"""
492 self.setUp()
493 getattr(self, self._testMethodName)()
494 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000495 while self._cleanups:
496 function, args, kwargs = self._cleanups.pop(-1)
497 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000498
499 def skipTest(self, reason):
500 """Skip this test."""
501 raise SkipTest(reason)
502
503 def fail(self, msg=None):
504 """Fail immediately, with the given message."""
505 raise self.failureException(msg)
506
507 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000508 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000509 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000510 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000511 raise self.failureException(msg)
512
513 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000514 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000515 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000516 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000517 raise self.failureException(msg)
518
519 def _formatMessage(self, msg, standardMsg):
520 """Honour the longMessage attribute when generating failure messages.
521 If longMessage is False this means:
522 * Use only an explicit message if it is provided
523 * Otherwise use the standard message for the assert
524
525 If longMessage is True:
526 * Use the standard message
527 * If an explicit message is provided, plus ' : ' and the explicit message
528 """
529 if not self.longMessage:
530 return msg or standardMsg
531 if msg is None:
532 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000533 try:
534 # don't switch to '{}' formatting in Python 2.X
535 # it changes the way unicode input is handled
536 return '%s : %s' % (standardMsg, msg)
537 except UnicodeDecodeError:
538 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000539
540
541 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
542 """Fail unless an exception of class excClass is thrown
543 by callableObj when invoked with arguments args and keyword
544 arguments kwargs. If a different type of exception is
545 thrown, it will not be caught, and the test case will be
546 deemed to have suffered an error, exactly as for an
547 unexpected exception.
548
549 If called with callableObj omitted or None, will return a
550 context object used like this::
551
Michael Foord1c42b122010-02-05 22:58:21 +0000552 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000553 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000554
555 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000556 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000557 exception after the assertion::
558
559 with self.assertRaises(SomeException) as cm:
560 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000561 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000562 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000563 """
564 context = _AssertRaisesContext(excClass, self, callableObj)
565 if callableObj is None:
566 return context
567 with context:
568 callableObj(*args, **kwargs)
569
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000570 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
571 """Fail unless a warning of class warnClass is triggered
572 by callableObj when invoked with arguments args and keyword
573 arguments kwargs. If a different type of warning is
574 triggered, it will not be handled: depending on the other
575 warning filtering rules in effect, it might be silenced, printed
576 out, or raised as an exception.
577
578 If called with callableObj omitted or None, will return a
579 context object used like this::
580
581 with self.assertWarns(SomeWarning):
582 do_something()
583
584 The context manager keeps a reference to the first matching
585 warning as the 'warning' attribute; similarly, the 'filename'
586 and 'lineno' attributes give you information about the line
587 of Python code from which the warning was triggered.
588 This allows you to inspect the warning after the assertion::
589
590 with self.assertWarns(SomeWarning) as cm:
591 do_something()
592 the_warning = cm.warning
593 self.assertEqual(the_warning.some_attribute, 147)
594 """
595 context = _AssertWarnsContext(expected_warning, self, callable_obj)
596 if callable_obj is None:
597 return context
598 with context:
599 callable_obj(*args, **kwargs)
600
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000601 def _getAssertEqualityFunc(self, first, second):
602 """Get a detailed comparison function for the types of the two args.
603
604 Returns: A callable accepting (first, second, msg=None) that will
605 raise a failure exception if first != second with a useful human
606 readable error message for those types.
607 """
608 #
609 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
610 # and vice versa. I opted for the conservative approach in case
611 # subclasses are not intended to be compared in detail to their super
612 # class instances using a type equality func. This means testing
613 # subtypes won't automagically use the detailed comparison. Callers
614 # should use their type specific assertSpamEqual method to compare
615 # subclasses if the detailed comparison is desired and appropriate.
616 # See the discussion in http://bugs.python.org/issue2578.
617 #
618 if type(first) is type(second):
619 asserter = self._type_equality_funcs.get(type(first))
620 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000621 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000622
623 return self._baseAssertEqual
624
625 def _baseAssertEqual(self, first, second, msg=None):
626 """The default assertEqual implementation, not type specific."""
627 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000628 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000629 msg = self._formatMessage(msg, standardMsg)
630 raise self.failureException(msg)
631
632 def assertEqual(self, first, second, msg=None):
633 """Fail if the two objects are unequal as determined by the '=='
634 operator.
635 """
636 assertion_func = self._getAssertEqualityFunc(first, second)
637 assertion_func(first, second, msg=msg)
638
639 def assertNotEqual(self, first, second, msg=None):
640 """Fail if the two objects are equal as determined by the '=='
641 operator.
642 """
643 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000644 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
645 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000646 raise self.failureException(msg)
647
Michael Foord321d0592010-11-02 13:44:51 +0000648 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000649 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000650 """Fail if the two objects are unequal as determined by their
651 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000652 (default 7) and comparing to zero, or by comparing that the
653 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000654
655 Note that decimal places (from zero) are usually not the same
656 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000657
658 If the two objects compare equal then they will automatically
659 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000660 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000661 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000662 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000663 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000664 if delta is not None and places is not None:
665 raise TypeError("specify delta or places not both")
666
667 if delta is not None:
668 if abs(first - second) <= delta:
669 return
670
671 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
672 safe_repr(second),
673 safe_repr(delta))
674 else:
675 if places is None:
676 places = 7
677
678 if round(abs(second-first), places) == 0:
679 return
680
Benjamin Peterson847a4112010-03-14 15:04:17 +0000681 standardMsg = '%s != %s within %r places' % (safe_repr(first),
682 safe_repr(second),
683 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000684 msg = self._formatMessage(msg, standardMsg)
685 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000686
Michael Foord321d0592010-11-02 13:44:51 +0000687 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000688 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000689 """Fail if the two objects are equal as determined by their
690 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000691 (default 7) and comparing to zero, or by comparing that the
692 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000693
694 Note that decimal places (from zero) are usually not the same
695 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000696
697 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000698 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000699 if delta is not None and places is not None:
700 raise TypeError("specify delta or places not both")
701 if delta is not None:
702 if not (first == second) and abs(first - second) > delta:
703 return
704 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
705 safe_repr(second),
706 safe_repr(delta))
707 else:
708 if places is None:
709 places = 7
710 if not (first == second) and round(abs(second-first), places) != 0:
711 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000712 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000713 safe_repr(second),
714 places)
715
716 msg = self._formatMessage(msg, standardMsg)
717 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000718
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000719
Michael Foord085dfd32010-06-05 12:17:02 +0000720 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000721 """An equality assertion for ordered sequences (like lists and tuples).
722
R. David Murrayad13f222010-01-29 22:17:58 +0000723 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000724 which can be indexed, has a length, and has an equality operator.
725
726 Args:
727 seq1: The first sequence to compare.
728 seq2: The second sequence to compare.
729 seq_type: The expected datatype of the sequences, or None if no
730 datatype should be enforced.
731 msg: Optional message to use on failure instead of a list of
732 differences.
733 """
734 if seq_type != None:
735 seq_type_name = seq_type.__name__
736 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000737 raise self.failureException('First sequence is not a %s: %s'
738 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000739 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000740 raise self.failureException('Second sequence is not a %s: %s'
741 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000742 else:
743 seq_type_name = "sequence"
744
745 differing = None
746 try:
747 len1 = len(seq1)
748 except (TypeError, NotImplementedError):
749 differing = 'First %s has no length. Non-sequence?' % (
750 seq_type_name)
751
752 if differing is None:
753 try:
754 len2 = len(seq2)
755 except (TypeError, NotImplementedError):
756 differing = 'Second %s has no length. Non-sequence?' % (
757 seq_type_name)
758
759 if differing is None:
760 if seq1 == seq2:
761 return
762
Benjamin Peterson847a4112010-03-14 15:04:17 +0000763 seq1_repr = safe_repr(seq1)
764 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000765 if len(seq1_repr) > 30:
766 seq1_repr = seq1_repr[:30] + '...'
767 if len(seq2_repr) > 30:
768 seq2_repr = seq2_repr[:30] + '...'
769 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
770 differing = '%ss differ: %s != %s\n' % elements
771
772 for i in range(min(len1, len2)):
773 try:
774 item1 = seq1[i]
775 except (TypeError, IndexError, NotImplementedError):
776 differing += ('\nUnable to index element %d of first %s\n' %
777 (i, seq_type_name))
778 break
779
780 try:
781 item2 = seq2[i]
782 except (TypeError, IndexError, NotImplementedError):
783 differing += ('\nUnable to index element %d of second %s\n' %
784 (i, seq_type_name))
785 break
786
787 if item1 != item2:
788 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
789 (i, item1, item2))
790 break
791 else:
792 if (len1 == len2 and seq_type is None and
793 type(seq1) != type(seq2)):
794 # The sequences are the same, but have differing types.
795 return
796
797 if len1 > len2:
798 differing += ('\nFirst %s contains %d additional '
799 'elements.\n' % (seq_type_name, len1 - len2))
800 try:
801 differing += ('First extra element %d:\n%s\n' %
802 (len2, seq1[len2]))
803 except (TypeError, IndexError, NotImplementedError):
804 differing += ('Unable to index element %d '
805 'of first %s\n' % (len2, seq_type_name))
806 elif len1 < len2:
807 differing += ('\nSecond %s contains %d additional '
808 'elements.\n' % (seq_type_name, len2 - len1))
809 try:
810 differing += ('First extra element %d:\n%s\n' %
811 (len1, seq2[len1]))
812 except (TypeError, IndexError, NotImplementedError):
813 differing += ('Unable to index element %d '
814 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000815 standardMsg = differing
816 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000817 difflib.ndiff(pprint.pformat(seq1).splitlines(),
818 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000819
820 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000821 msg = self._formatMessage(msg, standardMsg)
822 self.fail(msg)
823
Michael Foord085dfd32010-06-05 12:17:02 +0000824 def _truncateMessage(self, message, diff):
825 max_diff = self.maxDiff
826 if max_diff is None or len(diff) <= max_diff:
827 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000828 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000829
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000830 def assertListEqual(self, list1, list2, msg=None):
831 """A list-specific equality assertion.
832
833 Args:
834 list1: The first list to compare.
835 list2: The second list to compare.
836 msg: Optional message to use on failure instead of a list of
837 differences.
838
839 """
840 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
841
842 def assertTupleEqual(self, tuple1, tuple2, msg=None):
843 """A tuple-specific equality assertion.
844
845 Args:
846 tuple1: The first tuple to compare.
847 tuple2: The second tuple to compare.
848 msg: Optional message to use on failure instead of a list of
849 differences.
850 """
851 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
852
853 def assertSetEqual(self, set1, set2, msg=None):
854 """A set-specific equality assertion.
855
856 Args:
857 set1: The first set to compare.
858 set2: The second set to compare.
859 msg: Optional message to use on failure instead of a list of
860 differences.
861
Michael Foord91c9da32010-03-20 17:21:27 +0000862 assertSetEqual uses ducktyping to support different types of sets, and
863 is optimized for sets specifically (parameters must support a
864 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000865 """
866 try:
867 difference1 = set1.difference(set2)
868 except TypeError as e:
869 self.fail('invalid type when attempting set difference: %s' % e)
870 except AttributeError as e:
871 self.fail('first argument does not support set difference: %s' % e)
872
873 try:
874 difference2 = set2.difference(set1)
875 except TypeError as e:
876 self.fail('invalid type when attempting set difference: %s' % e)
877 except AttributeError as e:
878 self.fail('second argument does not support set difference: %s' % e)
879
880 if not (difference1 or difference2):
881 return
882
883 lines = []
884 if difference1:
885 lines.append('Items in the first set but not the second:')
886 for item in difference1:
887 lines.append(repr(item))
888 if difference2:
889 lines.append('Items in the second set but not the first:')
890 for item in difference2:
891 lines.append(repr(item))
892
893 standardMsg = '\n'.join(lines)
894 self.fail(self._formatMessage(msg, standardMsg))
895
896 def assertIn(self, member, container, msg=None):
897 """Just like self.assertTrue(a in b), but with a nicer default message."""
898 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000899 standardMsg = '%s not found in %s' % (safe_repr(member),
900 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000901 self.fail(self._formatMessage(msg, standardMsg))
902
903 def assertNotIn(self, member, container, msg=None):
904 """Just like self.assertTrue(a not in b), but with a nicer default message."""
905 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000906 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
907 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000908 self.fail(self._formatMessage(msg, standardMsg))
909
910 def assertIs(self, expr1, expr2, msg=None):
911 """Just like self.assertTrue(a is b), but with a nicer default message."""
912 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000913 standardMsg = '%s is not %s' % (safe_repr(expr1),
914 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000915 self.fail(self._formatMessage(msg, standardMsg))
916
917 def assertIsNot(self, expr1, expr2, msg=None):
918 """Just like self.assertTrue(a is not b), but with a nicer default message."""
919 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000920 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000921 self.fail(self._formatMessage(msg, standardMsg))
922
923 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000924 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
925 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000926
927 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000928 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000929 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000930 pprint.pformat(d1).splitlines(),
931 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000932 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000933 self.fail(self._formatMessage(msg, standardMsg))
934
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000935 def assertDictContainsSubset(self, subset, dictionary, msg=None):
936 """Checks whether dictionary is a superset of subset."""
Raymond Hettinger8ebe27f2010-12-21 19:24:26 +0000937 warnings.warn('assertDictContainsSubset is deprecated',
938 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000939 missing = []
940 mismatched = []
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000941 for key, value in subset.items():
942 if key not in dictionary:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000943 missing.append(key)
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000944 elif value != dictionary[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000945 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000946 (safe_repr(key), safe_repr(value),
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000947 safe_repr(dictionary[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000948
949 if not (missing or mismatched):
950 return
951
952 standardMsg = ''
953 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000954 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
955 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000956 if mismatched:
957 if standardMsg:
958 standardMsg += '; '
959 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
960
961 self.fail(self._formatMessage(msg, standardMsg))
962
963 def assertSameElements(self, expected_seq, actual_seq, msg=None):
964 """An unordered sequence specific comparison.
965
966 Raises with an error message listing which elements of expected_seq
967 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000968
969 Duplicate elements are ignored when comparing *expected_seq* and
970 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
971 set(actual))`` but it works with sequences of unhashable objects as
972 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000973 """
Michael Foord91c9da32010-03-20 17:21:27 +0000974 warnings.warn('assertSameElements is deprecated',
975 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000976 try:
977 expected = set(expected_seq)
978 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000979 missing = sorted(expected.difference(actual))
980 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000981 except TypeError:
982 # Fall back to slower list-compare if any of the objects are
983 # not hashable.
984 expected = list(expected_seq)
985 actual = list(actual_seq)
986 try:
987 expected.sort()
988 actual.sort()
989 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000990 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000991 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000992 else:
993 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000994 errors = []
995 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000996 errors.append('Expected, but missing:\n %s' %
997 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000998 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000999 errors.append('Unexpected, but present:\n %s' %
1000 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001001 if errors:
1002 standardMsg = '\n'.join(errors)
1003 self.fail(self._formatMessage(msg, standardMsg))
1004
Michael Foord8442a602010-03-20 16:58:04 +00001005
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001006 def assertCountEqual(self, actual, expected, msg=None):
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001007 """An unordered sequence specific comparison. It asserts that
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001008 actual_seq and expected_seq have the same element counts.
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001009 Equivalent to::
Michael Foord8442a602010-03-20 16:58:04 +00001010
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001011 self.assertEqual(Counter(actual_seq),
1012 Counter(expected_seq))
Michael Foord8442a602010-03-20 16:58:04 +00001013
1014 Asserts that each element has the same count in both sequences.
1015 Example:
1016 - [0, 1, 1] and [1, 0, 1] compare equal.
1017 - [0, 0, 1] and [0, 1] compare unequal.
1018 """
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001019 actual_seq, expected_seq = list(actual), list(expected)
Michael Foord8442a602010-03-20 16:58:04 +00001020 try:
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001021 actual = collections.Counter(actual_seq)
1022 expected = collections.Counter(expected_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001023 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +00001024 # Handle case with unhashable elements
Raymond Hettingerd65a9012010-12-23 21:54:02 +00001025 missing, unexpected = unorderable_list_difference(expected_seq, actual_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001026 else:
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001027 if actual == expected:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001028 return
1029 missing = list(expected - actual)
1030 unexpected = list(actual - expected)
Michael Foord8442a602010-03-20 16:58:04 +00001031
1032 errors = []
1033 if missing:
1034 errors.append('Expected, but missing:\n %s' %
1035 safe_repr(missing))
1036 if unexpected:
1037 errors.append('Unexpected, but present:\n %s' %
1038 safe_repr(unexpected))
1039 if errors:
1040 standardMsg = '\n'.join(errors)
1041 self.fail(self._formatMessage(msg, standardMsg))
1042
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