blob: b02d475c5d588b406ec2312222d7400c097a315e [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."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000937 missing = []
938 mismatched = []
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000939 for key, value in subset.items():
940 if key not in dictionary:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000941 missing.append(key)
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000942 elif value != dictionary[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000943 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000944 (safe_repr(key), safe_repr(value),
Ezio Melottiaddc6f52010-12-18 20:00:04 +0000945 safe_repr(dictionary[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000946
947 if not (missing or mismatched):
948 return
949
950 standardMsg = ''
951 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000952 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
953 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000954 if mismatched:
955 if standardMsg:
956 standardMsg += '; '
957 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
958
959 self.fail(self._formatMessage(msg, standardMsg))
960
961 def assertSameElements(self, expected_seq, actual_seq, msg=None):
962 """An unordered sequence specific comparison.
963
964 Raises with an error message listing which elements of expected_seq
965 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000966
967 Duplicate elements are ignored when comparing *expected_seq* and
968 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
969 set(actual))`` but it works with sequences of unhashable objects as
970 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000971 """
Michael Foord91c9da32010-03-20 17:21:27 +0000972 warnings.warn('assertSameElements is deprecated',
973 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000974 try:
975 expected = set(expected_seq)
976 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000977 missing = sorted(expected.difference(actual))
978 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000979 except TypeError:
980 # Fall back to slower list-compare if any of the objects are
981 # not hashable.
982 expected = list(expected_seq)
983 actual = list(actual_seq)
984 try:
985 expected.sort()
986 actual.sort()
987 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000988 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000989 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000990 else:
991 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000992 errors = []
993 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000994 errors.append('Expected, but missing:\n %s' %
995 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000996 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000997 errors.append('Unexpected, but present:\n %s' %
998 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000999 if errors:
1000 standardMsg = '\n'.join(errors)
1001 self.fail(self._formatMessage(msg, standardMsg))
1002
Michael Foord8442a602010-03-20 16:58:04 +00001003
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001004 def assertCountEqual(self, actual_seq, expected_seq, msg=None):
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001005 """An unordered sequence specific comparison. It asserts that
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001006 actual_seq and expected_seq have the same element counts.
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001007 Equivalent to::
Michael Foord8442a602010-03-20 16:58:04 +00001008
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001009 self.assertEqual(Counter(iter(actual_seq)),
1010 Counter(iter(expected_seq)))
Michael Foord8442a602010-03-20 16:58:04 +00001011
1012 Asserts that each element has the same count in both sequences.
1013 Example:
1014 - [0, 1, 1] and [1, 0, 1] compare equal.
1015 - [0, 0, 1] and [0, 1] compare unequal.
1016 """
1017 try:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001018 actual = collections.Counter(iter(actual_seq))
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001019 expected = collections.Counter(iter(expected_seq))
Michael Foord8442a602010-03-20 16:58:04 +00001020 except TypeError:
1021 # Unsortable items (example: set(), complex(), ...)
Michael Foord8442a602010-03-20 16:58:04 +00001022 actual = list(actual_seq)
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001023 expected = list(expected_seq)
Michael Foord8442a602010-03-20 16:58:04 +00001024 missing, unexpected = unorderable_list_difference(expected, actual)
1025 else:
Ezio Melottiaddc6f52010-12-18 20:00:04 +00001026 if actual == expected:
Raymond Hettinger6e165b32010-11-27 09:31:37 +00001027 return
1028 missing = list(expected - actual)
1029 unexpected = list(actual - expected)
Michael Foord8442a602010-03-20 16:58:04 +00001030
1031 errors = []
1032 if missing:
1033 errors.append('Expected, but missing:\n %s' %
1034 safe_repr(missing))
1035 if unexpected:
1036 errors.append('Unexpected, but present:\n %s' %
1037 safe_repr(unexpected))
1038 if errors:
1039 standardMsg = '\n'.join(errors)
1040 self.fail(self._formatMessage(msg, standardMsg))
1041
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001042 def assertMultiLineEqual(self, first, second, msg=None):
1043 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001044 self.assertIsInstance(first, str, 'First argument is not a string')
1045 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001046
1047 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001048 firstlines = first.splitlines(True)
1049 secondlines = second.splitlines(True)
1050 if len(firstlines) == 1 and first.strip('\r\n') == first:
1051 firstlines = [first + '\n']
1052 secondlines = [second + '\n']
1053 standardMsg = '%s != %s' % (safe_repr(first, True),
1054 safe_repr(second, True))
1055 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001056 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001057 self.fail(self._formatMessage(msg, standardMsg))
1058
1059 def assertLess(self, a, b, msg=None):
1060 """Just like self.assertTrue(a < b), but with a nicer default message."""
1061 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001062 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001063 self.fail(self._formatMessage(msg, standardMsg))
1064
1065 def assertLessEqual(self, a, b, msg=None):
1066 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1067 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001068 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001069 self.fail(self._formatMessage(msg, standardMsg))
1070
1071 def assertGreater(self, a, b, msg=None):
1072 """Just like self.assertTrue(a > b), but with a nicer default message."""
1073 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001074 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001075 self.fail(self._formatMessage(msg, standardMsg))
1076
1077 def assertGreaterEqual(self, a, b, msg=None):
1078 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1079 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001080 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001081 self.fail(self._formatMessage(msg, standardMsg))
1082
1083 def assertIsNone(self, obj, msg=None):
1084 """Same as self.assertTrue(obj is None), with a nicer default message."""
1085 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001086 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001087 self.fail(self._formatMessage(msg, standardMsg))
1088
1089 def assertIsNotNone(self, obj, msg=None):
1090 """Included for symmetry with assertIsNone."""
1091 if obj is None:
1092 standardMsg = 'unexpectedly None'
1093 self.fail(self._formatMessage(msg, standardMsg))
1094
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001095 def assertIsInstance(self, obj, cls, msg=None):
1096 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1097 default message."""
1098 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001099 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001100 self.fail(self._formatMessage(msg, standardMsg))
1101
1102 def assertNotIsInstance(self, obj, cls, msg=None):
1103 """Included for symmetry with assertIsInstance."""
1104 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001105 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001106 self.fail(self._formatMessage(msg, standardMsg))
1107
Ezio Melottied3a7d22010-12-01 02:32:32 +00001108 def assertRaisesRegex(self, expected_exception, expected_regex,
1109 callable_obj=None, *args, **kwargs):
1110 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001111
1112 Args:
1113 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001114 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001115 to be found in error message.
1116 callable_obj: Function to be called.
1117 args: Extra args.
1118 kwargs: Extra kwargs.
1119 """
1120 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001121 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001122 if callable_obj is None:
1123 return context
1124 with context:
1125 callable_obj(*args, **kwargs)
1126
Ezio Melottied3a7d22010-12-01 02:32:32 +00001127 def assertWarnsRegex(self, expected_warning, expected_regex,
1128 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001129 """Asserts that the message in a triggered warning matches a regexp.
1130 Basic functioning is similar to assertWarns() with the addition
1131 that only warnings whose messages also match the regular expression
1132 are considered successful matches.
1133
1134 Args:
1135 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001136 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001137 to be found in error message.
1138 callable_obj: Function to be called.
1139 args: Extra args.
1140 kwargs: Extra kwargs.
1141 """
1142 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001143 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001144 if callable_obj is None:
1145 return context
1146 with context:
1147 callable_obj(*args, **kwargs)
1148
Ezio Melottied3a7d22010-12-01 02:32:32 +00001149 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001150 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001151 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001152 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001153 expected_regex = re.compile(expected_regex)
1154 if not expected_regex.search(text):
1155 msg = msg or "Regex didn't match"
1156 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001157 raise self.failureException(msg)
1158
Ezio Melotti8f776302010-12-10 02:32:05 +00001159 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001160 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001161 if isinstance(unexpected_regex, (str, bytes)):
1162 unexpected_regex = re.compile(unexpected_regex)
1163 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001164 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001165 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001166 msg = '%s: %r matches %r in %r' % (msg,
1167 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001168 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001169 text)
1170 raise self.failureException(msg)
1171
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001172
Ezio Melottied3a7d22010-12-01 02:32:32 +00001173 def _deprecate(original_func):
1174 def deprecated_func(*args, **kwargs):
1175 warnings.warn(
1176 'Please use {0} instead.'.format(original_func.__name__),
1177 DeprecationWarning, 2)
1178 return original_func(*args, **kwargs)
1179 return deprecated_func
1180
1181 # The fail* methods can be removed in 3.3, the 5 assert* methods will
1182 # have to stay around for a few more versions. See #9424.
1183 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1184 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1185 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1186 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1187 failUnless = assert_ = _deprecate(assertTrue)
1188 failUnlessRaises = _deprecate(assertRaises)
1189 failIf = _deprecate(assertFalse)
1190 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1191 assertRegexpMatches = _deprecate(assertRegex)
1192
1193
1194
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001195class FunctionTestCase(TestCase):
1196 """A test case that wraps a test function.
1197
1198 This is useful for slipping pre-existing test functions into the
1199 unittest framework. Optionally, set-up and tidy-up functions can be
1200 supplied. As with TestCase, the tidy-up ('tearDown') function will
1201 always be called if the set-up ('setUp') function ran successfully.
1202 """
1203
1204 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1205 super(FunctionTestCase, self).__init__()
1206 self._setUpFunc = setUp
1207 self._tearDownFunc = tearDown
1208 self._testFunc = testFunc
1209 self._description = description
1210
1211 def setUp(self):
1212 if self._setUpFunc is not None:
1213 self._setUpFunc()
1214
1215 def tearDown(self):
1216 if self._tearDownFunc is not None:
1217 self._tearDownFunc()
1218
1219 def runTest(self):
1220 self._testFunc()
1221
1222 def id(self):
1223 return self._testFunc.__name__
1224
1225 def __eq__(self, other):
1226 if not isinstance(other, self.__class__):
1227 return NotImplemented
1228
1229 return self._setUpFunc == other._setUpFunc and \
1230 self._tearDownFunc == other._tearDownFunc and \
1231 self._testFunc == other._testFunc and \
1232 self._description == other._description
1233
1234 def __ne__(self, other):
1235 return not self == other
1236
1237 def __hash__(self):
1238 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1239 self._testFunc, self._description))
1240
1241 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001242 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001243 self._testFunc.__name__)
1244
1245 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001246 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001247 self._testFunc)
1248
1249 def shortDescription(self):
1250 if self._description is not None:
1251 return self._description
1252 doc = self._testFunc.__doc__
1253 return doc and doc.split("\n")[0].strip() or None