blob: 881de6ffa5bbb153f7ecbf7b89df5f5d9d21aa70 [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
Ezio Melottiedd117f2011-04-27 10:20:38 +0300266 # If a string is longer than _diffThreshold, use normal comparison instead
267 # of difflib. See #11763.
268 _diffThreshold = 2**16
269
Benjamin Peterson847a4112010-03-14 15:04:17 +0000270 # Attribute used by TestSuite for classSetUp
271
272 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000273
274 def __init__(self, methodName='runTest'):
275 """Create an instance of the class that will use the named test
276 method when executed. Raises a ValueError if the instance does
277 not have a method with the specified name.
278 """
279 self._testMethodName = methodName
Michael Foordb3468f72010-12-19 03:19:47 +0000280 self._outcomeForDoCleanups = None
Michael Foord32e1d832011-01-03 17:00:11 +0000281 self._testMethodDoc = 'No test'
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000282 try:
283 testMethod = getattr(self, methodName)
284 except AttributeError:
Michael Foord32e1d832011-01-03 17:00:11 +0000285 if methodName != 'runTest':
286 # we allow instantiation with no explicit method name
287 # but not an *incorrect* or missing method name
288 raise ValueError("no such test method in %s: %s" %
289 (self.__class__, methodName))
290 else:
291 self._testMethodDoc = testMethod.__doc__
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000292 self._cleanups = []
293
294 # Map types to custom assertEqual functions that will compare
295 # instances of said type in more detail to generate a more useful
296 # error message.
Michael Foord8ca6d982010-11-20 15:34:26 +0000297 self._type_equality_funcs = _TypeEqualityDict(self)
298 self.addTypeEqualityFunc(dict, 'assertDictEqual')
299 self.addTypeEqualityFunc(list, 'assertListEqual')
300 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
301 self.addTypeEqualityFunc(set, 'assertSetEqual')
302 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
303 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000304
305 def addTypeEqualityFunc(self, typeobj, function):
306 """Add a type specific assertEqual style function to compare a type.
307
308 This method is for use by TestCase subclasses that need to register
309 their own type equality functions to provide nicer error messages.
310
311 Args:
312 typeobj: The data type to call this function on when both values
313 are of the same type in assertEqual().
314 function: The callable taking two arguments and an optional
315 msg= argument that raises self.failureException with a
316 useful error message when the two arguments are not equal.
317 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000318 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000319
320 def addCleanup(self, function, *args, **kwargs):
321 """Add a function, with arguments, to be called when the test is
322 completed. Functions added are called on a LIFO basis and are
323 called after tearDown on test failure or success.
324
325 Cleanup items are called even if setUp fails (unlike tearDown)."""
326 self._cleanups.append((function, args, kwargs))
327
328 def setUp(self):
329 "Hook method for setting up the test fixture before exercising it."
330 pass
331
332 def tearDown(self):
333 "Hook method for deconstructing the test fixture after testing it."
334 pass
335
Benjamin Peterson847a4112010-03-14 15:04:17 +0000336 @classmethod
337 def setUpClass(cls):
338 "Hook method for setting up class fixture before running tests in the class."
339
340 @classmethod
341 def tearDownClass(cls):
342 "Hook method for deconstructing the class fixture after running all tests in the class."
343
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000344 def countTestCases(self):
345 return 1
346
347 def defaultTestResult(self):
348 return result.TestResult()
349
350 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000351 """Returns a one-line description of the test, or None if no
352 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000353
Michael Foord34c94622010-02-10 15:51:42 +0000354 The default implementation of this method returns the first line of
355 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000356 """
Michael Foord34c94622010-02-10 15:51:42 +0000357 doc = self._testMethodDoc
358 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000359
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000360
361 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000362 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000363
364 def __eq__(self, other):
365 if type(self) is not type(other):
366 return NotImplemented
367
368 return self._testMethodName == other._testMethodName
369
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000370 def __hash__(self):
371 return hash((type(self), self._testMethodName))
372
373 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000374 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000375
376 def __repr__(self):
377 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000378 (strclass(self.__class__), self._testMethodName)
379
380 def _addSkip(self, result, reason):
381 addSkip = getattr(result, 'addSkip', None)
382 if addSkip is not None:
383 addSkip(self, reason)
384 else:
385 warnings.warn("TestResult has no addSkip method, skips not reported",
386 RuntimeWarning, 2)
387 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000388
Michael Foordb3468f72010-12-19 03:19:47 +0000389 def _executeTestPart(self, function, outcome, isTest=False):
390 try:
391 function()
392 except KeyboardInterrupt:
393 raise
394 except SkipTest as e:
395 outcome.success = False
396 outcome.skipped = str(e)
397 except _UnexpectedSuccess:
398 exc_info = sys.exc_info()
399 outcome.success = False
400 if isTest:
401 outcome.unexpectedSuccess = exc_info
402 else:
403 outcome.errors.append(exc_info)
404 except _ExpectedFailure:
405 outcome.success = False
406 exc_info = sys.exc_info()
407 if isTest:
408 outcome.expectedFailure = exc_info
409 else:
410 outcome.errors.append(exc_info)
411 except self.failureException:
412 outcome.success = False
413 outcome.failures.append(sys.exc_info())
414 exc_info = sys.exc_info()
415 except:
416 outcome.success = False
417 outcome.errors.append(sys.exc_info())
418
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000419 def run(self, result=None):
420 orig_result = result
421 if result is None:
422 result = self.defaultTestResult()
423 startTestRun = getattr(result, 'startTestRun', None)
424 if startTestRun is not None:
425 startTestRun()
426
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000427 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000428
429 testMethod = getattr(self, self._testMethodName)
430 if (getattr(self.__class__, "__unittest_skip__", False) or
431 getattr(testMethod, "__unittest_skip__", False)):
432 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000433 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000434 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
435 or getattr(testMethod, '__unittest_skip_why__', ''))
436 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000437 finally:
438 result.stopTest(self)
439 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000440 try:
Michael Foordb3468f72010-12-19 03:19:47 +0000441 outcome = _Outcome()
442 self._outcomeForDoCleanups = outcome
443
444 self._executeTestPart(self.setUp, outcome)
445 if outcome.success:
446 self._executeTestPart(testMethod, outcome, isTest=True)
447 self._executeTestPart(self.tearDown, outcome)
448
449 self.doCleanups()
450 if outcome.success:
451 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000452 else:
Michael Foordb3468f72010-12-19 03:19:47 +0000453 if outcome.skipped is not None:
454 self._addSkip(result, outcome.skipped)
455 for exc_info in outcome.errors:
456 result.addError(self, exc_info)
457 for exc_info in outcome.failures:
458 result.addFailure(self, exc_info)
459 if outcome.unexpectedSuccess is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000460 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
461 if addUnexpectedSuccess is not None:
462 addUnexpectedSuccess(self)
463 else:
464 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
465 RuntimeWarning)
Michael Foordb3468f72010-12-19 03:19:47 +0000466 result.addFailure(self, outcome.unexpectedSuccess)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467
Michael Foordb3468f72010-12-19 03:19:47 +0000468 if outcome.expectedFailure is not None:
469 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
470 if addExpectedFailure is not None:
471 addExpectedFailure(self, outcome.expectedFailure)
472 else:
473 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
474 RuntimeWarning)
475 result.addSuccess(self)
Michael Foord1341bb02011-03-14 19:01:46 -0400476 return result
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000477 finally:
478 result.stopTest(self)
479 if orig_result is None:
480 stopTestRun = getattr(result, 'stopTestRun', None)
481 if stopTestRun is not None:
482 stopTestRun()
483
484 def doCleanups(self):
485 """Execute all cleanup functions. Normally called for you after
486 tearDown."""
Michael Foordb3468f72010-12-19 03:19:47 +0000487 outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000488 while self._cleanups:
Michael Foordb3468f72010-12-19 03:19:47 +0000489 function, args, kwargs = self._cleanups.pop()
490 part = lambda: function(*args, **kwargs)
491 self._executeTestPart(part, outcome)
492
493 # return this for backwards compatibility
494 # even though we no longer us it internally
495 return outcome.success
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000496
497 def __call__(self, *args, **kwds):
498 return self.run(*args, **kwds)
499
500 def debug(self):
501 """Run the test without collecting errors in a TestResult"""
502 self.setUp()
503 getattr(self, self._testMethodName)()
504 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000505 while self._cleanups:
506 function, args, kwargs = self._cleanups.pop(-1)
507 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000508
509 def skipTest(self, reason):
510 """Skip this test."""
511 raise SkipTest(reason)
512
513 def fail(self, msg=None):
514 """Fail immediately, with the given message."""
515 raise self.failureException(msg)
516
517 def assertFalse(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000518 """Check that the expression is false."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000519 if expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000520 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000521 raise self.failureException(msg)
522
523 def assertTrue(self, expr, msg=None):
Ezio Melotti3044fa72010-12-18 17:31:58 +0000524 """Check that the expression is true."""
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000525 if not expr:
Ezio Melotti3044fa72010-12-18 17:31:58 +0000526 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000527 raise self.failureException(msg)
528
529 def _formatMessage(self, msg, standardMsg):
530 """Honour the longMessage attribute when generating failure messages.
531 If longMessage is False this means:
532 * Use only an explicit message if it is provided
533 * Otherwise use the standard message for the assert
534
535 If longMessage is True:
536 * Use the standard message
537 * If an explicit message is provided, plus ' : ' and the explicit message
538 """
539 if not self.longMessage:
540 return msg or standardMsg
541 if msg is None:
542 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000543 try:
544 # don't switch to '{}' formatting in Python 2.X
545 # it changes the way unicode input is handled
546 return '%s : %s' % (standardMsg, msg)
547 except UnicodeDecodeError:
548 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000549
550
551 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
552 """Fail unless an exception of class excClass is thrown
553 by callableObj when invoked with arguments args and keyword
554 arguments kwargs. If a different type of exception is
555 thrown, it will not be caught, and the test case will be
556 deemed to have suffered an error, exactly as for an
557 unexpected exception.
558
559 If called with callableObj omitted or None, will return a
560 context object used like this::
561
Michael Foord1c42b122010-02-05 22:58:21 +0000562 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000563 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000564
565 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000566 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000567 exception after the assertion::
568
569 with self.assertRaises(SomeException) as cm:
570 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000571 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000572 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000573 """
574 context = _AssertRaisesContext(excClass, self, callableObj)
575 if callableObj is None:
576 return context
577 with context:
578 callableObj(*args, **kwargs)
579
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000580 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
581 """Fail unless a warning of class warnClass is triggered
582 by callableObj when invoked with arguments args and keyword
583 arguments kwargs. If a different type of warning is
584 triggered, it will not be handled: depending on the other
585 warning filtering rules in effect, it might be silenced, printed
586 out, or raised as an exception.
587
588 If called with callableObj omitted or None, will return a
589 context object used like this::
590
591 with self.assertWarns(SomeWarning):
592 do_something()
593
594 The context manager keeps a reference to the first matching
595 warning as the 'warning' attribute; similarly, the 'filename'
596 and 'lineno' attributes give you information about the line
597 of Python code from which the warning was triggered.
598 This allows you to inspect the warning after the assertion::
599
600 with self.assertWarns(SomeWarning) as cm:
601 do_something()
602 the_warning = cm.warning
603 self.assertEqual(the_warning.some_attribute, 147)
604 """
605 context = _AssertWarnsContext(expected_warning, self, callable_obj)
606 if callable_obj is None:
607 return context
608 with context:
609 callable_obj(*args, **kwargs)
610
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000611 def _getAssertEqualityFunc(self, first, second):
612 """Get a detailed comparison function for the types of the two args.
613
614 Returns: A callable accepting (first, second, msg=None) that will
615 raise a failure exception if first != second with a useful human
616 readable error message for those types.
617 """
618 #
619 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
620 # and vice versa. I opted for the conservative approach in case
621 # subclasses are not intended to be compared in detail to their super
622 # class instances using a type equality func. This means testing
623 # subtypes won't automagically use the detailed comparison. Callers
624 # should use their type specific assertSpamEqual method to compare
625 # subclasses if the detailed comparison is desired and appropriate.
626 # See the discussion in http://bugs.python.org/issue2578.
627 #
628 if type(first) is type(second):
629 asserter = self._type_equality_funcs.get(type(first))
630 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000631 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000632
633 return self._baseAssertEqual
634
635 def _baseAssertEqual(self, first, second, msg=None):
636 """The default assertEqual implementation, not type specific."""
637 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000638 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000639 msg = self._formatMessage(msg, standardMsg)
640 raise self.failureException(msg)
641
642 def assertEqual(self, first, second, msg=None):
643 """Fail if the two objects are unequal as determined by the '=='
644 operator.
645 """
646 assertion_func = self._getAssertEqualityFunc(first, second)
647 assertion_func(first, second, msg=msg)
648
649 def assertNotEqual(self, first, second, msg=None):
650 """Fail if the two objects are equal as determined by the '=='
651 operator.
652 """
653 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000654 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
655 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000656 raise self.failureException(msg)
657
Michael Foord321d0592010-11-02 13:44:51 +0000658 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000659 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000660 """Fail if the two objects are unequal as determined by their
661 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000662 (default 7) and comparing to zero, or by comparing that the
663 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000664
665 Note that decimal places (from zero) are usually not the same
666 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000667
668 If the two objects compare equal then they will automatically
669 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000670 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000671 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000672 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000673 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000674 if delta is not None and places is not None:
675 raise TypeError("specify delta or places not both")
676
677 if delta is not None:
678 if abs(first - second) <= delta:
679 return
680
681 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
682 safe_repr(second),
683 safe_repr(delta))
684 else:
685 if places is None:
686 places = 7
687
688 if round(abs(second-first), places) == 0:
689 return
690
Benjamin Peterson847a4112010-03-14 15:04:17 +0000691 standardMsg = '%s != %s within %r places' % (safe_repr(first),
692 safe_repr(second),
693 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000694 msg = self._formatMessage(msg, standardMsg)
695 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000696
Michael Foord321d0592010-11-02 13:44:51 +0000697 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000698 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699 """Fail if the two objects are equal as determined by their
700 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000701 (default 7) and comparing to zero, or by comparing that the
702 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000703
704 Note that decimal places (from zero) are usually not the same
705 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000706
707 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000708 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000709 if delta is not None and places is not None:
710 raise TypeError("specify delta or places not both")
711 if delta is not None:
712 if not (first == second) and abs(first - second) > delta:
713 return
714 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
715 safe_repr(second),
716 safe_repr(delta))
717 else:
718 if places is None:
719 places = 7
720 if not (first == second) and round(abs(second-first), places) != 0:
721 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000722 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000723 safe_repr(second),
724 places)
725
726 msg = self._formatMessage(msg, standardMsg)
727 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000728
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000729
Michael Foord085dfd32010-06-05 12:17:02 +0000730 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000731 """An equality assertion for ordered sequences (like lists and tuples).
732
R. David Murrayad13f222010-01-29 22:17:58 +0000733 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000734 which can be indexed, has a length, and has an equality operator.
735
736 Args:
737 seq1: The first sequence to compare.
738 seq2: The second sequence to compare.
739 seq_type: The expected datatype of the sequences, or None if no
740 datatype should be enforced.
741 msg: Optional message to use on failure instead of a list of
742 differences.
743 """
744 if seq_type != None:
745 seq_type_name = seq_type.__name__
746 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000747 raise self.failureException('First sequence is not a %s: %s'
748 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000749 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000750 raise self.failureException('Second sequence is not a %s: %s'
751 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000752 else:
753 seq_type_name = "sequence"
754
755 differing = None
756 try:
757 len1 = len(seq1)
758 except (TypeError, NotImplementedError):
759 differing = 'First %s has no length. Non-sequence?' % (
760 seq_type_name)
761
762 if differing is None:
763 try:
764 len2 = len(seq2)
765 except (TypeError, NotImplementedError):
766 differing = 'Second %s has no length. Non-sequence?' % (
767 seq_type_name)
768
769 if differing is None:
770 if seq1 == seq2:
771 return
772
Benjamin Peterson847a4112010-03-14 15:04:17 +0000773 seq1_repr = safe_repr(seq1)
774 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000775 if len(seq1_repr) > 30:
776 seq1_repr = seq1_repr[:30] + '...'
777 if len(seq2_repr) > 30:
778 seq2_repr = seq2_repr[:30] + '...'
779 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
780 differing = '%ss differ: %s != %s\n' % elements
781
782 for i in range(min(len1, len2)):
783 try:
784 item1 = seq1[i]
785 except (TypeError, IndexError, NotImplementedError):
786 differing += ('\nUnable to index element %d of first %s\n' %
787 (i, seq_type_name))
788 break
789
790 try:
791 item2 = seq2[i]
792 except (TypeError, IndexError, NotImplementedError):
793 differing += ('\nUnable to index element %d of second %s\n' %
794 (i, seq_type_name))
795 break
796
797 if item1 != item2:
798 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
799 (i, item1, item2))
800 break
801 else:
802 if (len1 == len2 and seq_type is None and
803 type(seq1) != type(seq2)):
804 # The sequences are the same, but have differing types.
805 return
806
807 if len1 > len2:
808 differing += ('\nFirst %s contains %d additional '
809 'elements.\n' % (seq_type_name, len1 - len2))
810 try:
811 differing += ('First extra element %d:\n%s\n' %
812 (len2, seq1[len2]))
813 except (TypeError, IndexError, NotImplementedError):
814 differing += ('Unable to index element %d '
815 'of first %s\n' % (len2, seq_type_name))
816 elif len1 < len2:
817 differing += ('\nSecond %s contains %d additional '
818 'elements.\n' % (seq_type_name, len2 - len1))
819 try:
820 differing += ('First extra element %d:\n%s\n' %
821 (len1, seq2[len1]))
822 except (TypeError, IndexError, NotImplementedError):
823 differing += ('Unable to index element %d '
824 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000825 standardMsg = differing
826 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000827 difflib.ndiff(pprint.pformat(seq1).splitlines(),
828 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000829
830 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000831 msg = self._formatMessage(msg, standardMsg)
832 self.fail(msg)
833
Michael Foord085dfd32010-06-05 12:17:02 +0000834 def _truncateMessage(self, message, diff):
835 max_diff = self.maxDiff
836 if max_diff is None or len(diff) <= max_diff:
837 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000838 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000839
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000840 def assertListEqual(self, list1, list2, msg=None):
841 """A list-specific equality assertion.
842
843 Args:
844 list1: The first list to compare.
845 list2: The second list to compare.
846 msg: Optional message to use on failure instead of a list of
847 differences.
848
849 """
850 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
851
852 def assertTupleEqual(self, tuple1, tuple2, msg=None):
853 """A tuple-specific equality assertion.
854
855 Args:
856 tuple1: The first tuple to compare.
857 tuple2: The second tuple to compare.
858 msg: Optional message to use on failure instead of a list of
859 differences.
860 """
861 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
862
863 def assertSetEqual(self, set1, set2, msg=None):
864 """A set-specific equality assertion.
865
866 Args:
867 set1: The first set to compare.
868 set2: The second set to compare.
869 msg: Optional message to use on failure instead of a list of
870 differences.
871
Michael Foord91c9da32010-03-20 17:21:27 +0000872 assertSetEqual uses ducktyping to support different types of sets, and
873 is optimized for sets specifically (parameters must support a
874 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000875 """
876 try:
877 difference1 = set1.difference(set2)
878 except TypeError as e:
879 self.fail('invalid type when attempting set difference: %s' % e)
880 except AttributeError as e:
881 self.fail('first argument does not support set difference: %s' % e)
882
883 try:
884 difference2 = set2.difference(set1)
885 except TypeError as e:
886 self.fail('invalid type when attempting set difference: %s' % e)
887 except AttributeError as e:
888 self.fail('second argument does not support set difference: %s' % e)
889
890 if not (difference1 or difference2):
891 return
892
893 lines = []
894 if difference1:
895 lines.append('Items in the first set but not the second:')
896 for item in difference1:
897 lines.append(repr(item))
898 if difference2:
899 lines.append('Items in the second set but not the first:')
900 for item in difference2:
901 lines.append(repr(item))
902
903 standardMsg = '\n'.join(lines)
904 self.fail(self._formatMessage(msg, standardMsg))
905
906 def assertIn(self, member, container, msg=None):
907 """Just like self.assertTrue(a in b), but with a nicer default message."""
908 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000909 standardMsg = '%s not found in %s' % (safe_repr(member),
910 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000911 self.fail(self._formatMessage(msg, standardMsg))
912
913 def assertNotIn(self, member, container, msg=None):
914 """Just like self.assertTrue(a not in b), but with a nicer default message."""
915 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000916 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
917 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000918 self.fail(self._formatMessage(msg, standardMsg))
919
920 def assertIs(self, expr1, expr2, msg=None):
921 """Just like self.assertTrue(a is b), but with a nicer default message."""
922 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000923 standardMsg = '%s is not %s' % (safe_repr(expr1),
924 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000925 self.fail(self._formatMessage(msg, standardMsg))
926
927 def assertIsNot(self, expr1, expr2, msg=None):
928 """Just like self.assertTrue(a is not b), but with a nicer default message."""
929 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000930 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000931 self.fail(self._formatMessage(msg, standardMsg))
932
933 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000934 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
935 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000936
937 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000938 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000939 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000940 pprint.pformat(d1).splitlines(),
941 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000942 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000943 self.fail(self._formatMessage(msg, standardMsg))
944
Ezio Melotti0f535012011-04-03 18:02:13 +0300945 def assertDictContainsSubset(self, subset, dictionary, msg=None):
946 """Checks whether dictionary is a superset of subset."""
947 warnings.warn('assertDictContainsSubset is deprecated',
948 DeprecationWarning)
949 missing = []
950 mismatched = []
951 for key, value in subset.items():
952 if key not in dictionary:
953 missing.append(key)
954 elif value != dictionary[key]:
955 mismatched.append('%s, expected: %s, actual: %s' %
956 (safe_repr(key), safe_repr(value),
957 safe_repr(dictionary[key])))
958
959 if not (missing or mismatched):
960 return
961
962 standardMsg = ''
963 if missing:
964 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
965 missing)
966 if mismatched:
967 if standardMsg:
968 standardMsg += '; '
969 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
970
971 self.fail(self._formatMessage(msg, standardMsg))
972
973
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000974 def assertCountEqual(self, first, second, msg=None):
975 """An unordered sequence comparison asserting that the same elements,
976 regardless of order. If the same element occurs more than once,
977 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000978
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000979 self.assertEqual(Counter(list(first)),
980 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000981
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000982 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000983 - [0, 1, 1] and [1, 0, 1] compare equal.
984 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000985
Michael Foord8442a602010-03-20 16:58:04 +0000986 """
Michael Foorde180d392011-01-28 19:51:48 +0000987 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +0000988 try:
Michael Foorde180d392011-01-28 19:51:48 +0000989 first = collections.Counter(first_seq)
990 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000991 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +0000992 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +0000993 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000994 else:
Michael Foorde180d392011-01-28 19:51:48 +0000995 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +0000996 return
Michael Foorde180d392011-01-28 19:51:48 +0000997 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000998
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000999 if differences:
1000 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +00001001 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +00001002 diffMsg = '\n'.join(lines)
1003 standardMsg = self._truncateMessage(standardMsg, diffMsg)
1004 msg = self._formatMessage(msg, standardMsg)
1005 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +00001006
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001007 def assertMultiLineEqual(self, first, second, msg=None):
1008 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +00001009 self.assertIsInstance(first, str, 'First argument is not a string')
1010 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001011
1012 if first != second:
Ezio Melottiedd117f2011-04-27 10:20:38 +03001013 # don't use difflib if the strings are too long
1014 if (len(first) > self._diffThreshold or
1015 len(second) > self._diffThreshold):
1016 self._baseAssertEqual(first, second, msg)
Michael Foordc653ce32010-07-10 13:52:22 +00001017 firstlines = first.splitlines(True)
1018 secondlines = second.splitlines(True)
1019 if len(firstlines) == 1 and first.strip('\r\n') == first:
1020 firstlines = [first + '\n']
1021 secondlines = [second + '\n']
1022 standardMsg = '%s != %s' % (safe_repr(first, True),
1023 safe_repr(second, True))
1024 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001025 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001026 self.fail(self._formatMessage(msg, standardMsg))
1027
1028 def assertLess(self, a, b, msg=None):
1029 """Just like self.assertTrue(a < b), but with a nicer default message."""
1030 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001031 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001032 self.fail(self._formatMessage(msg, standardMsg))
1033
1034 def assertLessEqual(self, a, b, msg=None):
1035 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1036 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001037 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001038 self.fail(self._formatMessage(msg, standardMsg))
1039
1040 def assertGreater(self, a, b, msg=None):
1041 """Just like self.assertTrue(a > b), but with a nicer default message."""
1042 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001043 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001044 self.fail(self._formatMessage(msg, standardMsg))
1045
1046 def assertGreaterEqual(self, a, b, msg=None):
1047 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1048 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001049 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001050 self.fail(self._formatMessage(msg, standardMsg))
1051
1052 def assertIsNone(self, obj, msg=None):
1053 """Same as self.assertTrue(obj is None), with a nicer default message."""
1054 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001055 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001056 self.fail(self._formatMessage(msg, standardMsg))
1057
1058 def assertIsNotNone(self, obj, msg=None):
1059 """Included for symmetry with assertIsNone."""
1060 if obj is None:
1061 standardMsg = 'unexpectedly None'
1062 self.fail(self._formatMessage(msg, standardMsg))
1063
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001064 def assertIsInstance(self, obj, cls, msg=None):
1065 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1066 default message."""
1067 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001068 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001069 self.fail(self._formatMessage(msg, standardMsg))
1070
1071 def assertNotIsInstance(self, obj, cls, msg=None):
1072 """Included for symmetry with assertIsInstance."""
1073 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001074 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001075 self.fail(self._formatMessage(msg, standardMsg))
1076
Ezio Melottied3a7d22010-12-01 02:32:32 +00001077 def assertRaisesRegex(self, expected_exception, expected_regex,
1078 callable_obj=None, *args, **kwargs):
1079 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001080
1081 Args:
1082 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001083 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001084 to be found in error message.
1085 callable_obj: Function to be called.
1086 args: Extra args.
1087 kwargs: Extra kwargs.
1088 """
1089 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001090 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001091 if callable_obj is None:
1092 return context
1093 with context:
1094 callable_obj(*args, **kwargs)
1095
Ezio Melottied3a7d22010-12-01 02:32:32 +00001096 def assertWarnsRegex(self, expected_warning, expected_regex,
1097 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001098 """Asserts that the message in a triggered warning matches a regexp.
1099 Basic functioning is similar to assertWarns() with the addition
1100 that only warnings whose messages also match the regular expression
1101 are considered successful matches.
1102
1103 Args:
1104 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001105 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001106 to be found in error message.
1107 callable_obj: Function to be called.
1108 args: Extra args.
1109 kwargs: Extra kwargs.
1110 """
1111 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001112 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001113 if callable_obj is None:
1114 return context
1115 with context:
1116 callable_obj(*args, **kwargs)
1117
Ezio Melottied3a7d22010-12-01 02:32:32 +00001118 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001119 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001120 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001121 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001122 expected_regex = re.compile(expected_regex)
1123 if not expected_regex.search(text):
1124 msg = msg or "Regex didn't match"
1125 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001126 raise self.failureException(msg)
1127
Ezio Melotti8f776302010-12-10 02:32:05 +00001128 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001129 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001130 if isinstance(unexpected_regex, (str, bytes)):
1131 unexpected_regex = re.compile(unexpected_regex)
1132 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001133 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001134 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001135 msg = '%s: %r matches %r in %r' % (msg,
1136 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001137 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001138 text)
1139 raise self.failureException(msg)
1140
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001141
Ezio Melottied3a7d22010-12-01 02:32:32 +00001142 def _deprecate(original_func):
1143 def deprecated_func(*args, **kwargs):
1144 warnings.warn(
1145 'Please use {0} instead.'.format(original_func.__name__),
1146 DeprecationWarning, 2)
1147 return original_func(*args, **kwargs)
1148 return deprecated_func
1149
Ezio Melotti361467e2011-04-03 17:37:58 +03001150 # see #9424
Ezio Melotti0f535012011-04-03 18:02:13 +03001151 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1152 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1153 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1154 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1155 failUnless = assert_ = _deprecate(assertTrue)
1156 failUnlessRaises = _deprecate(assertRaises)
1157 failIf = _deprecate(assertFalse)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001158 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1159 assertRegexpMatches = _deprecate(assertRegex)
1160
1161
1162
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001163class FunctionTestCase(TestCase):
1164 """A test case that wraps a test function.
1165
1166 This is useful for slipping pre-existing test functions into the
1167 unittest framework. Optionally, set-up and tidy-up functions can be
1168 supplied. As with TestCase, the tidy-up ('tearDown') function will
1169 always be called if the set-up ('setUp') function ran successfully.
1170 """
1171
1172 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1173 super(FunctionTestCase, self).__init__()
1174 self._setUpFunc = setUp
1175 self._tearDownFunc = tearDown
1176 self._testFunc = testFunc
1177 self._description = description
1178
1179 def setUp(self):
1180 if self._setUpFunc is not None:
1181 self._setUpFunc()
1182
1183 def tearDown(self):
1184 if self._tearDownFunc is not None:
1185 self._tearDownFunc()
1186
1187 def runTest(self):
1188 self._testFunc()
1189
1190 def id(self):
1191 return self._testFunc.__name__
1192
1193 def __eq__(self, other):
1194 if not isinstance(other, self.__class__):
1195 return NotImplemented
1196
1197 return self._setUpFunc == other._setUpFunc and \
1198 self._tearDownFunc == other._tearDownFunc and \
1199 self._testFunc == other._testFunc and \
1200 self._description == other._description
1201
1202 def __ne__(self, other):
1203 return not self == other
1204
1205 def __hash__(self):
1206 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1207 self._testFunc, self._description))
1208
1209 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001210 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001211 self._testFunc.__name__)
1212
1213 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001214 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001215 self._testFunc)
1216
1217 def shortDescription(self):
1218 if self._description is not None:
1219 return self._description
1220 doc = self._testFunc.__doc__
1221 return doc and doc.split("\n")[0].strip() or None