blob: 8086bf9b274c54b80bf7a2634d593bb24de059d8 [file] [log] [blame]
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001"""Test case implementation"""
2
3import sys
4import functools
5import difflib
6import pprint
7import re
8import warnings
Raymond Hettinger6e165b32010-11-27 09:31:37 +00009import collections
Benjamin Petersonbed7d042009-07-19 21:01:52 +000010
Benjamin Peterson847a4112010-03-14 15:04:17 +000011from . import result
12from .util import (strclass, safe_repr, sorted_list_difference,
Raymond Hettinger93e233d2010-12-24 10:02:22 +000013 unorderable_list_difference, _count_diff_all_purpose,
14 _count_diff_hashable)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000015
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000016__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000017
Michael Foord9dad32e2010-06-05 13:49:56 +000018
19DIFF_OMITTED = ('\nDiff is %s characters long. '
20 'Set self.maxDiff to None to see it.')
21
Benjamin Petersonbed7d042009-07-19 21:01:52 +000022class SkipTest(Exception):
23 """
24 Raise this exception in a test to skip it.
25
26 Usually you can use TestResult.skip() or one of the skipping decorators
27 instead of raising this directly.
28 """
Benjamin Petersonbed7d042009-07-19 21:01:52 +000029
30class _ExpectedFailure(Exception):
31 """
32 Raise this when a test is expected to fail.
33
34 This is an implementation detail.
35 """
36
37 def __init__(self, exc_info):
38 super(_ExpectedFailure, self).__init__()
39 self.exc_info = exc_info
40
41class _UnexpectedSuccess(Exception):
42 """
43 The test was supposed to fail, but it didn't!
44 """
Michael Foordb3468f72010-12-19 03:19:47 +000045
46
47class _Outcome(object):
48 def __init__(self):
49 self.success = True
50 self.skipped = None
51 self.unexpectedSuccess = None
52 self.expectedFailure = None
53 self.errors = []
54 self.failures = []
55
Benjamin Petersonbed7d042009-07-19 21:01:52 +000056
57def _id(obj):
58 return obj
59
60def skip(reason):
61 """
62 Unconditionally skip a test.
63 """
64 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000065 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
66 @functools.wraps(test_item)
67 def skip_wrapper(*args, **kwargs):
68 raise SkipTest(reason)
69 test_item = skip_wrapper
70
71 test_item.__unittest_skip__ = True
72 test_item.__unittest_skip_why__ = reason
73 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000074 return decorator
75
76def skipIf(condition, reason):
77 """
78 Skip a test if the condition is true.
79 """
80 if condition:
81 return skip(reason)
82 return _id
83
84def skipUnless(condition, reason):
85 """
86 Skip a test unless the condition is true.
87 """
88 if not condition:
89 return skip(reason)
90 return _id
91
92
93def expectedFailure(func):
94 @functools.wraps(func)
95 def wrapper(*args, **kwargs):
96 try:
97 func(*args, **kwargs)
98 except Exception:
99 raise _ExpectedFailure(sys.exc_info())
100 raise _UnexpectedSuccess
101 return wrapper
102
103
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000104class _AssertRaisesBaseContext(object):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000105
106 def __init__(self, expected, test_case, callable_obj=None,
Ezio Melottied3a7d22010-12-01 02:32:32 +0000107 expected_regex=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000108 self.expected = expected
109 self.failureException = test_case.failureException
110 if callable_obj is not None:
111 try:
112 self.obj_name = callable_obj.__name__
113 except AttributeError:
114 self.obj_name = str(callable_obj)
115 else:
116 self.obj_name = None
Ezio Melottied3a7d22010-12-01 02:32:32 +0000117 if isinstance(expected_regex, (bytes, str)):
118 expected_regex = re.compile(expected_regex)
119 self.expected_regex = expected_regex
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000120
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000121
122class _AssertRaisesContext(_AssertRaisesBaseContext):
123 """A context manager used to implement TestCase.assertRaises* methods."""
124
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000125 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000126 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000127
128 def __exit__(self, exc_type, exc_value, tb):
129 if exc_type is None:
130 try:
131 exc_name = self.expected.__name__
132 except AttributeError:
133 exc_name = str(self.expected)
134 if self.obj_name:
135 raise self.failureException("{0} not raised by {1}"
136 .format(exc_name, self.obj_name))
137 else:
138 raise self.failureException("{0} not raised"
139 .format(exc_name))
140 if not issubclass(exc_type, self.expected):
141 # let unexpected exceptions pass through
142 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000143 # store exception, without traceback, for later retrieval
144 self.exception = exc_value.with_traceback(None)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000145 if self.expected_regex is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000146 return True
147
Ezio Melottied3a7d22010-12-01 02:32:32 +0000148 expected_regex = self.expected_regex
149 if not expected_regex.search(str(exc_value)):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000150 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000151 (expected_regex.pattern, str(exc_value)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000152 return True
153
154
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000155class _AssertWarnsContext(_AssertRaisesBaseContext):
156 """A context manager used to implement TestCase.assertWarns* methods."""
157
158 def __enter__(self):
159 # The __warningregistry__'s need to be in a pristine state for tests
160 # to work properly.
161 for v in sys.modules.values():
162 if getattr(v, '__warningregistry__', None):
163 v.__warningregistry__ = {}
164 self.warnings_manager = warnings.catch_warnings(record=True)
165 self.warnings = self.warnings_manager.__enter__()
166 warnings.simplefilter("always", self.expected)
167 return self
168
169 def __exit__(self, exc_type, exc_value, tb):
170 self.warnings_manager.__exit__(exc_type, exc_value, tb)
171 if exc_type is not None:
172 # let unexpected exceptions pass through
173 return
174 try:
175 exc_name = self.expected.__name__
176 except AttributeError:
177 exc_name = str(self.expected)
178 first_matching = None
179 for m in self.warnings:
180 w = m.message
181 if not isinstance(w, self.expected):
182 continue
183 if first_matching is None:
184 first_matching = w
Ezio Melottied3a7d22010-12-01 02:32:32 +0000185 if (self.expected_regex is not None and
186 not self.expected_regex.search(str(w))):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000187 continue
188 # store warning for later retrieval
189 self.warning = w
190 self.filename = m.filename
191 self.lineno = m.lineno
192 return
193 # Now we simply try to choose a helpful failure message
194 if first_matching is not None:
195 raise self.failureException('"%s" does not match "%s"' %
Ezio Melottied3a7d22010-12-01 02:32:32 +0000196 (self.expected_regex.pattern, str(first_matching)))
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000197 if self.obj_name:
198 raise self.failureException("{0} not triggered by {1}"
199 .format(exc_name, self.obj_name))
200 else:
201 raise self.failureException("{0} not triggered"
202 .format(exc_name))
203
204
Michael Foord8ca6d982010-11-20 15:34:26 +0000205class _TypeEqualityDict(object):
206
207 def __init__(self, testcase):
208 self.testcase = testcase
209 self._store = {}
210
211 def __setitem__(self, key, value):
212 self._store[key] = value
213
214 def __getitem__(self, key):
215 value = self._store[key]
216 if isinstance(value, str):
217 return getattr(self.testcase, value)
218 return value
219
220 def get(self, key, default=None):
221 if key in self._store:
222 return self[key]
223 return default
224
225
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000226class TestCase(object):
227 """A class whose instances are single test cases.
228
229 By default, the test code itself should be placed in a method named
230 'runTest'.
231
232 If the fixture may be used for many test cases, create as
233 many test methods as are needed. When instantiating such a TestCase
234 subclass, specify in the constructor arguments the name of the test method
235 that the instance is to execute.
236
237 Test authors should subclass TestCase for their own tests. Construction
238 and deconstruction of the test's environment ('fixture') can be
239 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
240
241 If it is necessary to override the __init__ method, the base class
242 __init__ method must always be called. It is important that subclasses
243 should not change the signature of their __init__ method, since instances
244 of the classes are instantiated automatically by parts of the framework
245 in order to be run.
246 """
247
248 # This attribute determines which exception will be raised when
249 # the instance's assertion methods fail; test methods raising this
250 # exception will be deemed to have 'failed' rather than 'errored'
251
252 failureException = AssertionError
253
254 # This attribute determines whether long messages (including repr of
255 # objects used in assert methods) will be printed on failure in *addition*
256 # to any explicit message passed.
257
Michael Foord5074df62010-12-03 00:53:09 +0000258 longMessage = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000259
Michael Foordc41d1412010-06-10 16:17:07 +0000260 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000261 # by assert methods using difflib. It is looked up as an instance attribute
262 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000263
Michael Foord085dfd32010-06-05 12:17:02 +0000264 maxDiff = 80*8
265
Benjamin Peterson847a4112010-03-14 15:04:17 +0000266 # Attribute used by TestSuite for classSetUp
267
268 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000269
270 def __init__(self, methodName='runTest'):
271 """Create an instance of the class that will use the named test
272 method when executed. Raises a ValueError if the instance does
273 not have a method with the specified name.
274 """
275 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000276 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000277 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000278 try:
279 testMethod = getattr(self, methodName)
280 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000281 if methodName != 'runTest':
282 # we allow instantiation with no explicit method name
283 # but not an *incorrect* or missing method name
284 raise ValueError("no such test method in %s: %s" %
285 (self.__class__, methodName))
286 else:
287 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000288 self._cleanups = []
289
290 # Map types to custom assertEqual functions that will compare
291 # instances of said type in more detail to generate a more useful
292 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000293 self._type_equality_funcs = _TypeEqualityDict(self)
294 self.addTypeEqualityFunc(dict, 'assertDictEqual')
295 self.addTypeEqualityFunc(list, 'assertListEqual')
296 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
297 self.addTypeEqualityFunc(set, 'assertSetEqual')
298 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
299 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000300
301 def addTypeEqualityFunc(self, typeobj, function):
302 """Add a type specific assertEqual style function to compare a type.
303
304 This method is for use by TestCase subclasses that need to register
305 their own type equality functions to provide nicer error messages.
306
307 Args:
308 typeobj: The data type to call this function on when both values
309 are of the same type in assertEqual().
310 function: The callable taking two arguments and an optional
311 msg= argument that raises self.failureException with a
312 useful error message when the two arguments are not equal.
313 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000314 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000315
316 def addCleanup(self, function, *args, **kwargs):
317 """Add a function, with arguments, to be called when the test is
318 completed. Functions added are called on a LIFO basis and are
319 called after tearDown on test failure or success.
320
321 Cleanup items are called even if setUp fails (unlike tearDown)."""
322 self._cleanups.append((function, args, kwargs))
323
324 def setUp(self):
325 "Hook method for setting up the test fixture before exercising it."
326 pass
327
328 def tearDown(self):
329 "Hook method for deconstructing the test fixture after testing it."
330 pass
331
Benjamin Peterson847a4112010-03-14 15:04:17 +0000332 @classmethod
333 def setUpClass(cls):
334 "Hook method for setting up class fixture before running tests in the class."
335
336 @classmethod
337 def tearDownClass(cls):
338 "Hook method for deconstructing the class fixture after running all tests in the class."
339
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000340 def countTestCases(self):
341 return 1
342
343 def defaultTestResult(self):
344 return result.TestResult()
345
346 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000347 """Returns a one-line description of the test, or None if no
348 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000349
Michael Foord34c94622010-02-10 15:51:42 +0000350 The default implementation of this method returns the first line of
351 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000352 """
Michael Foord34c94622010-02-10 15:51:42 +0000353 doc = self._testMethodDoc
354 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000355
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000356
357 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000358 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000359
360 def __eq__(self, other):
361 if type(self) is not type(other):
362 return NotImplemented
363
364 return self._testMethodName == other._testMethodName
365
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000366 def __hash__(self):
367 return hash((type(self), self._testMethodName))
368
369 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000370 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000371
372 def __repr__(self):
373 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000374 (strclass(self.__class__), self._testMethodName)
375
376 def _addSkip(self, result, reason):
377 addSkip = getattr(result, 'addSkip', None)
378 if addSkip is not None:
379 addSkip(self, reason)
380 else:
381 warnings.warn("TestResult has no addSkip method, skips not reported",
382 RuntimeWarning, 2)
383 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000384
Michael Foordb3468f72010-12-19 03:19:47 +0000385 def _executeTestPart(self, function, outcome, isTest=False):
386 try:
387 function()
388 except KeyboardInterrupt:
389 raise
390 except SkipTest as e:
391 outcome.success = False
392 outcome.skipped = str(e)
393 except _UnexpectedSuccess:
394 exc_info = sys.exc_info()
395 outcome.success = False
396 if isTest:
397 outcome.unexpectedSuccess = exc_info
398 else:
399 outcome.errors.append(exc_info)
400 except _ExpectedFailure:
401 outcome.success = False
402 exc_info = sys.exc_info()
403 if isTest:
404 outcome.expectedFailure = exc_info
405 else:
406 outcome.errors.append(exc_info)
407 except self.failureException:
408 outcome.success = False
409 outcome.failures.append(sys.exc_info())
410 exc_info = sys.exc_info()
411 except:
412 outcome.success = False
413 outcome.errors.append(sys.exc_info())
414
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000415 def run(self, result=None):
416 orig_result = result
417 if result is None:
418 result = self.defaultTestResult()
419 startTestRun = getattr(result, 'startTestRun', None)
420 if startTestRun is not None:
421 startTestRun()
422
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000423 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000424
425 testMethod = getattr(self, self._testMethodName)
426 if (getattr(self.__class__, "__unittest_skip__", False) or
427 getattr(testMethod, "__unittest_skip__", False)):
428 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000429 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000430 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
431 or getattr(testMethod, '__unittest_skip_why__', ''))
432 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000433 finally:
434 result.stopTest(self)
435 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000436 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000437 outcome = _Outcome()
438 self._outcomeForDoCleanups = outcome
439
440 self._executeTestPart(self.setUp, outcome)
441 if outcome.success:
442 self._executeTestPart(testMethod, outcome, isTest=True)
443 self._executeTestPart(self.tearDown, outcome)
444
445 self.doCleanups()
446 if outcome.success:
447 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000449 if outcome.skipped is not None:
450 self._addSkip(result, outcome.skipped)
451 for exc_info in outcome.errors:
452 result.addError(self, exc_info)
453 for exc_info in outcome.failures:
454 result.addFailure(self, exc_info)
455 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000456 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
457 if addUnexpectedSuccess is not None:
458 addUnexpectedSuccess(self)
459 else:
460 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
461 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000462 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000463
Michael Foordb3468f72010-12-19 03:19:47 +0000464 if outcome.expectedFailure is not None:
465 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
466 if addExpectedFailure is not None:
467 addExpectedFailure(self, outcome.expectedFailure)
468 else:
469 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
470 RuntimeWarning)
471 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400472 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000473 finally:
474 result.stopTest(self)
475 if orig_result is None:
476 stopTestRun = getattr(result, 'stopTestRun', None)
477 if stopTestRun is not None:
478 stopTestRun()
479
480 def doCleanups(self):
481 """Execute all cleanup functions. Normally called for you after
482 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000483 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000484 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000485 function, args, kwargs = self._cleanups.pop()
486 part = lambda: function(*args, **kwargs)
487 self._executeTestPart(part, outcome)
488
489 # return this for backwards compatibility
490 # even though we no longer us it internally
491 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000492
493 def __call__(self, *args, **kwds):
494 return self.run(*args, **kwds)
495
496 def debug(self):
497 """Run the test without collecting errors in a TestResult"""
498 self.setUp()
499 getattr(self, self._testMethodName)()
500 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000501 while self._cleanups:
502 function, args, kwargs = self._cleanups.pop(-1)
503 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504
505 def skipTest(self, reason):
506 """Skip this test."""
507 raise SkipTest(reason)
508
509 def fail(self, msg=None):
510 """Fail immediately, with the given message."""
511 raise self.failureException(msg)
512
513 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000514 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000515 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000516 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000517 raise self.failureException(msg)
518
519 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000520 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000521 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000522 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000523 raise self.failureException(msg)
524
525 def _formatMessage(self, msg, standardMsg):
526 """Honour the longMessage attribute when generating failure messages.
527 If longMessage is False this means:
528 * Use only an explicit message if it is provided
529 * Otherwise use the standard message for the assert
530
531 If longMessage is True:
532 * Use the standard message
533 * If an explicit message is provided, plus ' : ' and the explicit message
534 """
535 if not self.longMessage:
536 return msg or standardMsg
537 if msg is None:
538 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000539 try:
540 # don't switch to '{}' formatting in Python 2.X
541 # it changes the way unicode input is handled
542 return '%s : %s' % (standardMsg, msg)
543 except UnicodeDecodeError:
544 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000545
546
547 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
548 """Fail unless an exception of class excClass is thrown
549 by callableObj when invoked with arguments args and keyword
550 arguments kwargs. If a different type of exception is
551 thrown, it will not be caught, and the test case will be
552 deemed to have suffered an error, exactly as for an
553 unexpected exception.
554
555 If called with callableObj omitted or None, will return a
556 context object used like this::
557
Michael Foord1c42b122010-02-05 22:58:21 +0000558 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000559 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000560
561 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000562 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000563 exception after the assertion::
564
565 with self.assertRaises(SomeException) as cm:
566 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000567 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000568 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000569 """
570 context = _AssertRaisesContext(excClass, self, callableObj)
571 if callableObj is None:
572 return context
573 with context:
574 callableObj(*args, **kwargs)
575
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000576 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
577 """Fail unless a warning of class warnClass is triggered
578 by callableObj when invoked with arguments args and keyword
579 arguments kwargs. If a different type of warning is
580 triggered, it will not be handled: depending on the other
581 warning filtering rules in effect, it might be silenced, printed
582 out, or raised as an exception.
583
584 If called with callableObj omitted or None, will return a
585 context object used like this::
586
587 with self.assertWarns(SomeWarning):
588 do_something()
589
590 The context manager keeps a reference to the first matching
591 warning as the 'warning' attribute; similarly, the 'filename'
592 and 'lineno' attributes give you information about the line
593 of Python code from which the warning was triggered.
594 This allows you to inspect the warning after the assertion::
595
596 with self.assertWarns(SomeWarning) as cm:
597 do_something()
598 the_warning = cm.warning
599 self.assertEqual(the_warning.some_attribute, 147)
600 """
601 context = _AssertWarnsContext(expected_warning, self, callable_obj)
602 if callable_obj is None:
603 return context
604 with context:
605 callable_obj(*args, **kwargs)
606
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000607 def _getAssertEqualityFunc(self, first, second):
608 """Get a detailed comparison function for the types of the two args.
609
610 Returns: A callable accepting (first, second, msg=None) that will
611 raise a failure exception if first != second with a useful human
612 readable error message for those types.
613 """
614 #
615 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
616 # and vice versa. I opted for the conservative approach in case
617 # subclasses are not intended to be compared in detail to their super
618 # class instances using a type equality func. This means testing
619 # subtypes won't automagically use the detailed comparison. Callers
620 # should use their type specific assertSpamEqual method to compare
621 # subclasses if the detailed comparison is desired and appropriate.
622 # See the discussion in http://bugs.python.org/issue2578.
623 #
624 if type(first) is type(second):
625 asserter = self._type_equality_funcs.get(type(first))
626 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000627 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000628
629 return self._baseAssertEqual
630
631 def _baseAssertEqual(self, first, second, msg=None):
632 """The default assertEqual implementation, not type specific."""
633 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000634 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000635 msg = self._formatMessage(msg, standardMsg)
636 raise self.failureException(msg)
637
638 def assertEqual(self, first, second, msg=None):
639 """Fail if the two objects are unequal as determined by the '=='
640 operator.
641 """
642 assertion_func = self._getAssertEqualityFunc(first, second)
643 assertion_func(first, second, msg=msg)
644
645 def assertNotEqual(self, first, second, msg=None):
646 """Fail if the two objects are equal as determined by the '=='
647 operator.
648 """
649 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000650 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
651 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000652 raise self.failureException(msg)
653
Michael Foord321d0592010-11-02 13:44:51 +0000654 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000655 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656 """Fail if the two objects are unequal as determined by their
657 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000658 (default 7) and comparing to zero, or by comparing that the
659 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000660
661 Note that decimal places (from zero) are usually not the same
662 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000663
664 If the two objects compare equal then they will automatically
665 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000666 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000667 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000668 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000669 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000670 if delta is not None and places is not None:
671 raise TypeError("specify delta or places not both")
672
673 if delta is not None:
674 if abs(first - second) <= delta:
675 return
676
677 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
678 safe_repr(second),
679 safe_repr(delta))
680 else:
681 if places is None:
682 places = 7
683
684 if round(abs(second-first), places) == 0:
685 return
686
Benjamin Peterson847a4112010-03-14 15:04:17 +0000687 standardMsg = '%s != %s within %r places' % (safe_repr(first),
688 safe_repr(second),
689 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000690 msg = self._formatMessage(msg, standardMsg)
691 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000692
Michael Foord321d0592010-11-02 13:44:51 +0000693 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000694 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000695 """Fail if the two objects are equal as determined by their
696 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000697 (default 7) and comparing to zero, or by comparing that the
698 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699
700 Note that decimal places (from zero) are usually not the same
701 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000702
703 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000704 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000705 if delta is not None and places is not None:
706 raise TypeError("specify delta or places not both")
707 if delta is not None:
708 if not (first == second) and abs(first - second) > delta:
709 return
710 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
711 safe_repr(second),
712 safe_repr(delta))
713 else:
714 if places is None:
715 places = 7
716 if not (first == second) and round(abs(second-first), places) != 0:
717 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000718 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000719 safe_repr(second),
720 places)
721
722 msg = self._formatMessage(msg, standardMsg)
723 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000724
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000725
Michael Foord085dfd32010-06-05 12:17:02 +0000726 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000727 """An equality assertion for ordered sequences (like lists and tuples).
728
R. David Murrayad13f222010-01-29 22:17:58 +0000729 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000730 which can be indexed, has a length, and has an equality operator.
731
732 Args:
733 seq1: The first sequence to compare.
734 seq2: The second sequence to compare.
735 seq_type: The expected datatype of the sequences, or None if no
736 datatype should be enforced.
737 msg: Optional message to use on failure instead of a list of
738 differences.
739 """
740 if seq_type != None:
741 seq_type_name = seq_type.__name__
742 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000743 raise self.failureException('First sequence is not a %s: %s'
744 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000745 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000746 raise self.failureException('Second sequence is not a %s: %s'
747 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000748 else:
749 seq_type_name = "sequence"
750
751 differing = None
752 try:
753 len1 = len(seq1)
754 except (TypeError, NotImplementedError):
755 differing = 'First %s has no length. Non-sequence?' % (
756 seq_type_name)
757
758 if differing is None:
759 try:
760 len2 = len(seq2)
761 except (TypeError, NotImplementedError):
762 differing = 'Second %s has no length. Non-sequence?' % (
763 seq_type_name)
764
765 if differing is None:
766 if seq1 == seq2:
767 return
768
Benjamin Peterson847a4112010-03-14 15:04:17 +0000769 seq1_repr = safe_repr(seq1)
770 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000771 if len(seq1_repr) > 30:
772 seq1_repr = seq1_repr[:30] + '...'
773 if len(seq2_repr) > 30:
774 seq2_repr = seq2_repr[:30] + '...'
775 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
776 differing = '%ss differ: %s != %s\n' % elements
777
778 for i in range(min(len1, len2)):
779 try:
780 item1 = seq1[i]
781 except (TypeError, IndexError, NotImplementedError):
782 differing += ('\nUnable to index element %d of first %s\n' %
783 (i, seq_type_name))
784 break
785
786 try:
787 item2 = seq2[i]
788 except (TypeError, IndexError, NotImplementedError):
789 differing += ('\nUnable to index element %d of second %s\n' %
790 (i, seq_type_name))
791 break
792
793 if item1 != item2:
794 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
795 (i, item1, item2))
796 break
797 else:
798 if (len1 == len2 and seq_type is None and
799 type(seq1) != type(seq2)):
800 # The sequences are the same, but have differing types.
801 return
802
803 if len1 > len2:
804 differing += ('\nFirst %s contains %d additional '
805 'elements.\n' % (seq_type_name, len1 - len2))
806 try:
807 differing += ('First extra element %d:\n%s\n' %
808 (len2, seq1[len2]))
809 except (TypeError, IndexError, NotImplementedError):
810 differing += ('Unable to index element %d '
811 'of first %s\n' % (len2, seq_type_name))
812 elif len1 < len2:
813 differing += ('\nSecond %s contains %d additional '
814 'elements.\n' % (seq_type_name, len2 - len1))
815 try:
816 differing += ('First extra element %d:\n%s\n' %
817 (len1, seq2[len1]))
818 except (TypeError, IndexError, NotImplementedError):
819 differing += ('Unable to index element %d '
820 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000821 standardMsg = differing
822 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000823 difflib.ndiff(pprint.pformat(seq1).splitlines(),
824 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000825
826 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000827 msg = self._formatMessage(msg, standardMsg)
828 self.fail(msg)
829
Michael Foord085dfd32010-06-05 12:17:02 +0000830 def _truncateMessage(self, message, diff):
831 max_diff = self.maxDiff
832 if max_diff is None or len(diff) <= max_diff:
833 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000834 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000835
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000836 def assertListEqual(self, list1, list2, msg=None):
837 """A list-specific equality assertion.
838
839 Args:
840 list1: The first list to compare.
841 list2: The second list to compare.
842 msg: Optional message to use on failure instead of a list of
843 differences.
844
845 """
846 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
847
848 def assertTupleEqual(self, tuple1, tuple2, msg=None):
849 """A tuple-specific equality assertion.
850
851 Args:
852 tuple1: The first tuple to compare.
853 tuple2: The second tuple to compare.
854 msg: Optional message to use on failure instead of a list of
855 differences.
856 """
857 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
858
859 def assertSetEqual(self, set1, set2, msg=None):
860 """A set-specific equality assertion.
861
862 Args:
863 set1: The first set to compare.
864 set2: The second set to compare.
865 msg: Optional message to use on failure instead of a list of
866 differences.
867
Michael Foord91c9da32010-03-20 17:21:27 +0000868 assertSetEqual uses ducktyping to support different types of sets, and
869 is optimized for sets specifically (parameters must support a
870 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000871 """
872 try:
873 difference1 = set1.difference(set2)
874 except TypeError as e:
875 self.fail('invalid type when attempting set difference: %s' % e)
876 except AttributeError as e:
877 self.fail('first argument does not support set difference: %s' % e)
878
879 try:
880 difference2 = set2.difference(set1)
881 except TypeError as e:
882 self.fail('invalid type when attempting set difference: %s' % e)
883 except AttributeError as e:
884 self.fail('second argument does not support set difference: %s' % e)
885
886 if not (difference1 or difference2):
887 return
888
889 lines = []
890 if difference1:
891 lines.append('Items in the first set but not the second:')
892 for item in difference1:
893 lines.append(repr(item))
894 if difference2:
895 lines.append('Items in the second set but not the first:')
896 for item in difference2:
897 lines.append(repr(item))
898
899 standardMsg = '\n'.join(lines)
900 self.fail(self._formatMessage(msg, standardMsg))
901
902 def assertIn(self, member, container, msg=None):
903 """Just like self.assertTrue(a in b), but with a nicer default message."""
904 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000905 standardMsg = '%s not found in %s' % (safe_repr(member),
906 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000907 self.fail(self._formatMessage(msg, standardMsg))
908
909 def assertNotIn(self, member, container, msg=None):
910 """Just like self.assertTrue(a not in b), but with a nicer default message."""
911 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000912 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
913 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000914 self.fail(self._formatMessage(msg, standardMsg))
915
916 def assertIs(self, expr1, expr2, msg=None):
917 """Just like self.assertTrue(a is b), but with a nicer default message."""
918 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000919 standardMsg = '%s is not %s' % (safe_repr(expr1),
920 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000921 self.fail(self._formatMessage(msg, standardMsg))
922
923 def assertIsNot(self, expr1, expr2, msg=None):
924 """Just like self.assertTrue(a is not b), but with a nicer default message."""
925 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000926 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000927 self.fail(self._formatMessage(msg, standardMsg))
928
929 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000930 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
931 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000932
933 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000934 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000935 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000936 pprint.pformat(d1).splitlines(),
937 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000938 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000939 self.fail(self._formatMessage(msg, standardMsg))
940
Ezio Melotti0f535012011-04-03 18:02:13 +0300941 def assertDictContainsSubset(self, subset, dictionary, msg=None):
942 """Checks whether dictionary is a superset of subset."""
943 warnings.warn('assertDictContainsSubset is deprecated',
944 DeprecationWarning)
945 missing = []
946 mismatched = []
947 for key, value in subset.items():
948 if key not in dictionary:
949 missing.append(key)
950 elif value != dictionary[key]:
951 mismatched.append('%s, expected: %s, actual: %s' %
952 (safe_repr(key), safe_repr(value),
953 safe_repr(dictionary[key])))
954
955 if not (missing or mismatched):
956 return
957
958 standardMsg = ''
959 if missing:
960 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
961 missing)
962 if mismatched:
963 if standardMsg:
964 standardMsg += '; '
965 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
966
967 self.fail(self._formatMessage(msg, standardMsg))
968
969
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000970 def assertCountEqual(self, first, second, msg=None):
971 """An unordered sequence comparison asserting that the same elements,
972 regardless of order. If the same element occurs more than once,
973 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000974
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000975 self.assertEqual(Counter(list(first)),
976 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000977
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000978 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000979 - [0, 1, 1] and [1, 0, 1] compare equal.
980 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000981
Michael Foord8442a602010-03-20 16:58:04 +0000982 """
Michael Foorde180d392011-01-28 19:51:48 +0000983 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +0000984 try:
Michael Foorde180d392011-01-28 19:51:48 +0000985 first = collections.Counter(first_seq)
986 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000987 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +0000988 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +0000989 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000990 else:
Michael Foorde180d392011-01-28 19:51:48 +0000991 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +0000992 return
Michael Foorde180d392011-01-28 19:51:48 +0000993 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000994
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000995 if differences:
996 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000997 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000998 diffMsg = '\n'.join(lines)
999 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1000 msg = self._formatMessage(msg, standardMsg)
1001 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001002
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001003 def assertMultiLineEqual(self, first, second, msg=None):
1004 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001005 self.assertIsInstance(first, str, 'First argument is not a string')
1006 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001007
1008 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001009 firstlines = first.splitlines(True)
1010 secondlines = second.splitlines(True)
1011 if len(firstlines) == 1 and first.strip('\r\n') == first:
1012 firstlines = [first + '\n']
1013 secondlines = [second + '\n']
1014 standardMsg = '%s != %s' % (safe_repr(first, True),
1015 safe_repr(second, True))
1016 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001017 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001018 self.fail(self._formatMessage(msg, standardMsg))
1019
1020 def assertLess(self, a, b, msg=None):
1021 """Just like self.assertTrue(a < b), but with a nicer default message."""
1022 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001023 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001024 self.fail(self._formatMessage(msg, standardMsg))
1025
1026 def assertLessEqual(self, a, b, msg=None):
1027 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1028 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001029 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001030 self.fail(self._formatMessage(msg, standardMsg))
1031
1032 def assertGreater(self, a, b, msg=None):
1033 """Just like self.assertTrue(a > b), but with a nicer default message."""
1034 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001035 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001036 self.fail(self._formatMessage(msg, standardMsg))
1037
1038 def assertGreaterEqual(self, a, b, msg=None):
1039 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1040 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001041 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001042 self.fail(self._formatMessage(msg, standardMsg))
1043
1044 def assertIsNone(self, obj, msg=None):
1045 """Same as self.assertTrue(obj is None), with a nicer default message."""
1046 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001047 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001048 self.fail(self._formatMessage(msg, standardMsg))
1049
1050 def assertIsNotNone(self, obj, msg=None):
1051 """Included for symmetry with assertIsNone."""
1052 if obj is None:
1053 standardMsg = 'unexpectedly None'
1054 self.fail(self._formatMessage(msg, standardMsg))
1055
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001056 def assertIsInstance(self, obj, cls, msg=None):
1057 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1058 default message."""
1059 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001060 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001061 self.fail(self._formatMessage(msg, standardMsg))
1062
1063 def assertNotIsInstance(self, obj, cls, msg=None):
1064 """Included for symmetry with assertIsInstance."""
1065 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001066 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001067 self.fail(self._formatMessage(msg, standardMsg))
1068
Ezio Melottied3a7d22010-12-01 02:32:32 +00001069 def assertRaisesRegex(self, expected_exception, expected_regex,
1070 callable_obj=None, *args, **kwargs):
1071 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001072
1073 Args:
1074 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001075 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001076 to be found in error message.
1077 callable_obj: Function to be called.
1078 args: Extra args.
1079 kwargs: Extra kwargs.
1080 """
1081 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001082 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001083 if callable_obj is None:
1084 return context
1085 with context:
1086 callable_obj(*args, **kwargs)
1087
Ezio Melottied3a7d22010-12-01 02:32:32 +00001088 def assertWarnsRegex(self, expected_warning, expected_regex,
1089 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001090 """Asserts that the message in a triggered warning matches a regexp.
1091 Basic functioning is similar to assertWarns() with the addition
1092 that only warnings whose messages also match the regular expression
1093 are considered successful matches.
1094
1095 Args:
1096 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001097 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001098 to be found in error message.
1099 callable_obj: Function to be called.
1100 args: Extra args.
1101 kwargs: Extra kwargs.
1102 """
1103 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001104 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001105 if callable_obj is None:
1106 return context
1107 with context:
1108 callable_obj(*args, **kwargs)
1109
Ezio Melottied3a7d22010-12-01 02:32:32 +00001110 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001111 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001112 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001113 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001114 expected_regex = re.compile(expected_regex)
1115 if not expected_regex.search(text):
1116 msg = msg or "Regex didn't match"
1117 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001118 raise self.failureException(msg)
1119
Ezio Melotti8f776302010-12-10 02:32:05 +00001120 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001121 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001122 if isinstance(unexpected_regex, (str, bytes)):
1123 unexpected_regex = re.compile(unexpected_regex)
1124 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001125 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001126 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001127 msg = '%s: %r matches %r in %r' % (msg,
1128 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001129 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001130 text)
1131 raise self.failureException(msg)
1132
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001133
Ezio Melottied3a7d22010-12-01 02:32:32 +00001134 def _deprecate(original_func):
1135 def deprecated_func(*args, **kwargs):
1136 warnings.warn(
1137 'Please use {0} instead.'.format(original_func.__name__),
1138 DeprecationWarning, 2)
1139 return original_func(*args, **kwargs)
1140 return deprecated_func
1141
Ezio Melotti361467e2011-04-03 17:37:58 +03001142 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001143 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1144 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1145 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1146 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1147 failUnless = assert_ = _deprecate(assertTrue)
1148 failUnlessRaises = _deprecate(assertRaises)
1149 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001150 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1151 assertRegexpMatches = _deprecate(assertRegex)
1152
1153
1154
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001155class FunctionTestCase(TestCase):
1156 """A test case that wraps a test function.
1157
1158 This is useful for slipping pre-existing test functions into the
1159 unittest framework. Optionally, set-up and tidy-up functions can be
1160 supplied. As with TestCase, the tidy-up ('tearDown') function will
1161 always be called if the set-up ('setUp') function ran successfully.
1162 """
1163
1164 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1165 super(FunctionTestCase, self).__init__()
1166 self._setUpFunc = setUp
1167 self._tearDownFunc = tearDown
1168 self._testFunc = testFunc
1169 self._description = description
1170
1171 def setUp(self):
1172 if self._setUpFunc is not None:
1173 self._setUpFunc()
1174
1175 def tearDown(self):
1176 if self._tearDownFunc is not None:
1177 self._tearDownFunc()
1178
1179 def runTest(self):
1180 self._testFunc()
1181
1182 def id(self):
1183 return self._testFunc.__name__
1184
1185 def __eq__(self, other):
1186 if not isinstance(other, self.__class__):
1187 return NotImplemented
1188
1189 return self._setUpFunc == other._setUpFunc and \
1190 self._tearDownFunc == other._tearDownFunc and \
1191 self._testFunc == other._testFunc and \
1192 self._description == other._description
1193
1194 def __ne__(self, other):
1195 return not self == other
1196
1197 def __hash__(self):
1198 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1199 self._testFunc, self._description))
1200
1201 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001202 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001203 self._testFunc.__name__)
1204
1205 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001206 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001207 self._testFunc)
1208
1209 def shortDescription(self):
1210 if self._description is not None:
1211 return self._description
1212 doc = self._testFunc.__doc__
1213 return doc and doc.split("\n")[0].strip() or None