blob: 4e477076b9a646140d36316356d8da0c67bfd552 [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
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000941 def assertCountEqual(self, first, second, msg=None):
942 """An unordered sequence comparison asserting that the same elements,
943 regardless of order. If the same element occurs more than once,
944 it verifies that the elements occur the same number of times.
Michael Foord8442a602010-03-20 16:58:04 +0000945
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000946 self.assertEqual(Counter(list(first)),
947 Counter(list(second)))
Michael Foord8442a602010-03-20 16:58:04 +0000948
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000949 Example:
Michael Foord8442a602010-03-20 16:58:04 +0000950 - [0, 1, 1] and [1, 0, 1] compare equal.
951 - [0, 0, 1] and [0, 1] compare unequal.
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000952
Michael Foord8442a602010-03-20 16:58:04 +0000953 """
Michael Foorde180d392011-01-28 19:51:48 +0000954 first_seq, second_seq = list(first), list(second)
Michael Foord8442a602010-03-20 16:58:04 +0000955 try:
Michael Foorde180d392011-01-28 19:51:48 +0000956 first = collections.Counter(first_seq)
957 second = collections.Counter(second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000958 except TypeError:
Raymond Hettinger6518f5e2010-12-24 00:52:54 +0000959 # Handle case with unhashable elements
Michael Foorde180d392011-01-28 19:51:48 +0000960 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000961 else:
Michael Foorde180d392011-01-28 19:51:48 +0000962 if first == second:
Raymond Hettinger6e165b32010-11-27 09:31:37 +0000963 return
Michael Foorde180d392011-01-28 19:51:48 +0000964 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord8442a602010-03-20 16:58:04 +0000965
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000966 if differences:
967 standardMsg = 'Element counts were not equal:\n'
Raymond Hettinger57bd00a2010-12-24 21:51:48 +0000968 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
Raymond Hettinger93e233d2010-12-24 10:02:22 +0000969 diffMsg = '\n'.join(lines)
970 standardMsg = self._truncateMessage(standardMsg, diffMsg)
971 msg = self._formatMessage(msg, standardMsg)
972 self.fail(msg)
Michael Foord8442a602010-03-20 16:58:04 +0000973
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000974 def assertMultiLineEqual(self, first, second, msg=None):
975 """Assert that two multi-line strings are equal."""
Ezio Melottib3aedd42010-11-20 19:04:17 +0000976 self.assertIsInstance(first, str, 'First argument is not a string')
977 self.assertIsInstance(second, str, 'Second argument is not a string')
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000978
979 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +0000980 firstlines = first.splitlines(True)
981 secondlines = second.splitlines(True)
982 if len(firstlines) == 1 and first.strip('\r\n') == first:
983 firstlines = [first + '\n']
984 secondlines = [second + '\n']
985 standardMsg = '%s != %s' % (safe_repr(first, True),
986 safe_repr(second, True))
987 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +0000988 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000989 self.fail(self._formatMessage(msg, standardMsg))
990
991 def assertLess(self, a, b, msg=None):
992 """Just like self.assertTrue(a < b), but with a nicer default message."""
993 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000994 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000995 self.fail(self._formatMessage(msg, standardMsg))
996
997 def assertLessEqual(self, a, b, msg=None):
998 """Just like self.assertTrue(a <= b), but with a nicer default message."""
999 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001000 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001001 self.fail(self._formatMessage(msg, standardMsg))
1002
1003 def assertGreater(self, a, b, msg=None):
1004 """Just like self.assertTrue(a > b), but with a nicer default message."""
1005 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001006 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001007 self.fail(self._formatMessage(msg, standardMsg))
1008
1009 def assertGreaterEqual(self, a, b, msg=None):
1010 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1011 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001012 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001013 self.fail(self._formatMessage(msg, standardMsg))
1014
1015 def assertIsNone(self, obj, msg=None):
1016 """Same as self.assertTrue(obj is None), with a nicer default message."""
1017 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001018 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001019 self.fail(self._formatMessage(msg, standardMsg))
1020
1021 def assertIsNotNone(self, obj, msg=None):
1022 """Included for symmetry with assertIsNone."""
1023 if obj is None:
1024 standardMsg = 'unexpectedly None'
1025 self.fail(self._formatMessage(msg, standardMsg))
1026
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001027 def assertIsInstance(self, obj, cls, msg=None):
1028 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1029 default message."""
1030 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001031 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001032 self.fail(self._formatMessage(msg, standardMsg))
1033
1034 def assertNotIsInstance(self, obj, cls, msg=None):
1035 """Included for symmetry with assertIsInstance."""
1036 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001037 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001038 self.fail(self._formatMessage(msg, standardMsg))
1039
Ezio Melottied3a7d22010-12-01 02:32:32 +00001040 def assertRaisesRegex(self, expected_exception, expected_regex,
1041 callable_obj=None, *args, **kwargs):
1042 """Asserts that the message in a raised exception matches a regex.
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001043
1044 Args:
1045 expected_exception: Exception class expected to be raised.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001046 expected_regex: Regex (re pattern object or string) expected
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001047 to be found in error message.
1048 callable_obj: Function to be called.
1049 args: Extra args.
1050 kwargs: Extra kwargs.
1051 """
1052 context = _AssertRaisesContext(expected_exception, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001053 expected_regex)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001054 if callable_obj is None:
1055 return context
1056 with context:
1057 callable_obj(*args, **kwargs)
1058
Ezio Melottied3a7d22010-12-01 02:32:32 +00001059 def assertWarnsRegex(self, expected_warning, expected_regex,
1060 callable_obj=None, *args, **kwargs):
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001061 """Asserts that the message in a triggered warning matches a regexp.
1062 Basic functioning is similar to assertWarns() with the addition
1063 that only warnings whose messages also match the regular expression
1064 are considered successful matches.
1065
1066 Args:
1067 expected_warning: Warning class expected to be triggered.
Ezio Melottied3a7d22010-12-01 02:32:32 +00001068 expected_regex: Regex (re pattern object or string) expected
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001069 to be found in error message.
1070 callable_obj: Function to be called.
1071 args: Extra args.
1072 kwargs: Extra kwargs.
1073 """
1074 context = _AssertWarnsContext(expected_warning, self, callable_obj,
Ezio Melottied3a7d22010-12-01 02:32:32 +00001075 expected_regex)
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001076 if callable_obj is None:
1077 return context
1078 with context:
1079 callable_obj(*args, **kwargs)
1080
Ezio Melottied3a7d22010-12-01 02:32:32 +00001081 def assertRegex(self, text, expected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001082 """Fail the test unless the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001083 if isinstance(expected_regex, (str, bytes)):
Gregory P. Smithed16bf42010-12-16 19:23:05 +00001084 assert expected_regex, "expected_regex must not be empty."
Ezio Melottied3a7d22010-12-01 02:32:32 +00001085 expected_regex = re.compile(expected_regex)
1086 if not expected_regex.search(text):
1087 msg = msg or "Regex didn't match"
1088 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001089 raise self.failureException(msg)
1090
Ezio Melotti8f776302010-12-10 02:32:05 +00001091 def assertNotRegex(self, text, unexpected_regex, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001092 """Fail the test if the text matches the regular expression."""
Ezio Melottied3a7d22010-12-01 02:32:32 +00001093 if isinstance(unexpected_regex, (str, bytes)):
1094 unexpected_regex = re.compile(unexpected_regex)
1095 match = unexpected_regex.search(text)
Benjamin Petersonb48af542010-04-11 20:43:16 +00001096 if match:
Ezio Melottied3a7d22010-12-01 02:32:32 +00001097 msg = msg or "Regex matched"
Benjamin Petersonb48af542010-04-11 20:43:16 +00001098 msg = '%s: %r matches %r in %r' % (msg,
1099 text[match.start():match.end()],
Ezio Melottied3a7d22010-12-01 02:32:32 +00001100 unexpected_regex.pattern,
Benjamin Petersonb48af542010-04-11 20:43:16 +00001101 text)
1102 raise self.failureException(msg)
1103
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001104
Ezio Melottied3a7d22010-12-01 02:32:32 +00001105 def _deprecate(original_func):
1106 def deprecated_func(*args, **kwargs):
1107 warnings.warn(
1108 'Please use {0} instead.'.format(original_func.__name__),
1109 DeprecationWarning, 2)
1110 return original_func(*args, **kwargs)
1111 return deprecated_func
1112
1113 # The fail* methods can be removed in 3.3, the 5 assert* methods will
1114 # have to stay around for a few more versions. See #9424.
Georg Brandl2cebdd42011-02-20 11:18:09 +00001115 assertEquals = _deprecate(assertEqual)
1116 assertNotEquals = _deprecate(assertNotEqual)
1117 assertAlmostEquals = _deprecate(assertAlmostEqual)
1118 assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1119 assert_ = _deprecate(assertTrue)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001120 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1121 assertRegexpMatches = _deprecate(assertRegex)
1122
1123
1124
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001125class FunctionTestCase(TestCase):
1126 """A test case that wraps a test function.
1127
1128 This is useful for slipping pre-existing test functions into the
1129 unittest framework. Optionally, set-up and tidy-up functions can be
1130 supplied. As with TestCase, the tidy-up ('tearDown') function will
1131 always be called if the set-up ('setUp') function ran successfully.
1132 """
1133
1134 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1135 super(FunctionTestCase, self).__init__()
1136 self._setUpFunc = setUp
1137 self._tearDownFunc = tearDown
1138 self._testFunc = testFunc
1139 self._description = description
1140
1141 def setUp(self):
1142 if self._setUpFunc is not None:
1143 self._setUpFunc()
1144
1145 def tearDown(self):
1146 if self._tearDownFunc is not None:
1147 self._tearDownFunc()
1148
1149 def runTest(self):
1150 self._testFunc()
1151
1152 def id(self):
1153 return self._testFunc.__name__
1154
1155 def __eq__(self, other):
1156 if not isinstance(other, self.__class__):
1157 return NotImplemented
1158
1159 return self._setUpFunc == other._setUpFunc and \
1160 self._tearDownFunc == other._tearDownFunc and \
1161 self._testFunc == other._testFunc and \
1162 self._description == other._description
1163
1164 def __ne__(self, other):
1165 return not self == other
1166
1167 def __hash__(self):
1168 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1169 self._testFunc, self._description))
1170
1171 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001172 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001173 self._testFunc.__name__)
1174
1175 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001176 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001177 self._testFunc)
1178
1179 def shortDescription(self):
1180 if self._description is not None:
1181 return self._description
1182 doc = self._testFunc.__doc__
1183 return doc and doc.split("\n")[0].strip() or None