blob: 4a13f0a6751fbbb06382e1c4abfef32729fdaf2f [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
9
Benjamin Peterson847a4112010-03-14 15:04:17 +000010from . import result
11from .util import (strclass, safe_repr, sorted_list_difference,
12 unorderable_list_difference)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000013
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000014__unittest = True
Michael Foord2034d9a2010-06-05 11:27:52 +000015TRUNCATED_DIFF = '\n[diff truncated...]'
Benjamin Petersonbed7d042009-07-19 21:01:52 +000016
17class SkipTest(Exception):
18 """
19 Raise this exception in a test to skip it.
20
21 Usually you can use TestResult.skip() or one of the skipping decorators
22 instead of raising this directly.
23 """
24 pass
25
26class _ExpectedFailure(Exception):
27 """
28 Raise this when a test is expected to fail.
29
30 This is an implementation detail.
31 """
32
33 def __init__(self, exc_info):
34 super(_ExpectedFailure, self).__init__()
35 self.exc_info = exc_info
36
37class _UnexpectedSuccess(Exception):
38 """
39 The test was supposed to fail, but it didn't!
40 """
41 pass
42
43def _id(obj):
44 return obj
45
46def skip(reason):
47 """
48 Unconditionally skip a test.
49 """
50 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000051 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
52 @functools.wraps(test_item)
53 def skip_wrapper(*args, **kwargs):
54 raise SkipTest(reason)
55 test_item = skip_wrapper
56
57 test_item.__unittest_skip__ = True
58 test_item.__unittest_skip_why__ = reason
59 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000060 return decorator
61
62def skipIf(condition, reason):
63 """
64 Skip a test if the condition is true.
65 """
66 if condition:
67 return skip(reason)
68 return _id
69
70def skipUnless(condition, reason):
71 """
72 Skip a test unless the condition is true.
73 """
74 if not condition:
75 return skip(reason)
76 return _id
77
78
79def expectedFailure(func):
80 @functools.wraps(func)
81 def wrapper(*args, **kwargs):
82 try:
83 func(*args, **kwargs)
84 except Exception:
85 raise _ExpectedFailure(sys.exc_info())
86 raise _UnexpectedSuccess
87 return wrapper
88
89
90class _AssertRaisesContext(object):
91 """A context manager used to implement TestCase.assertRaises* methods."""
92
93 def __init__(self, expected, test_case, callable_obj=None,
94 expected_regexp=None):
95 self.expected = expected
96 self.failureException = test_case.failureException
97 if callable_obj is not None:
98 try:
99 self.obj_name = callable_obj.__name__
100 except AttributeError:
101 self.obj_name = str(callable_obj)
102 else:
103 self.obj_name = None
Georg Brandl89fad142010-03-14 10:23:39 +0000104 self.expected_regexp = expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000105
106 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000107 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000108
109 def __exit__(self, exc_type, exc_value, tb):
110 if exc_type is None:
111 try:
112 exc_name = self.expected.__name__
113 except AttributeError:
114 exc_name = str(self.expected)
115 if self.obj_name:
116 raise self.failureException("{0} not raised by {1}"
117 .format(exc_name, self.obj_name))
118 else:
119 raise self.failureException("{0} not raised"
120 .format(exc_name))
121 if not issubclass(exc_type, self.expected):
122 # let unexpected exceptions pass through
123 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000124 # store exception, without traceback, for later retrieval
125 self.exception = exc_value.with_traceback(None)
Georg Brandl89fad142010-03-14 10:23:39 +0000126 if self.expected_regexp is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000127 return True
128
Georg Brandl89fad142010-03-14 10:23:39 +0000129 expected_regexp = self.expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000130 if isinstance(expected_regexp, (bytes, str)):
131 expected_regexp = re.compile(expected_regexp)
132 if not expected_regexp.search(str(exc_value)):
133 raise self.failureException('"%s" does not match "%s"' %
134 (expected_regexp.pattern, str(exc_value)))
135 return True
136
137
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138class TestCase(object):
139 """A class whose instances are single test cases.
140
141 By default, the test code itself should be placed in a method named
142 'runTest'.
143
144 If the fixture may be used for many test cases, create as
145 many test methods as are needed. When instantiating such a TestCase
146 subclass, specify in the constructor arguments the name of the test method
147 that the instance is to execute.
148
149 Test authors should subclass TestCase for their own tests. Construction
150 and deconstruction of the test's environment ('fixture') can be
151 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
152
153 If it is necessary to override the __init__ method, the base class
154 __init__ method must always be called. It is important that subclasses
155 should not change the signature of their __init__ method, since instances
156 of the classes are instantiated automatically by parts of the framework
157 in order to be run.
158 """
159
160 # This attribute determines which exception will be raised when
161 # the instance's assertion methods fail; test methods raising this
162 # exception will be deemed to have 'failed' rather than 'errored'
163
164 failureException = AssertionError
165
166 # This attribute determines whether long messages (including repr of
167 # objects used in assert methods) will be printed on failure in *addition*
168 # to any explicit message passed.
169
170 longMessage = False
171
Benjamin Peterson847a4112010-03-14 15:04:17 +0000172 # Attribute used by TestSuite for classSetUp
173
174 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000175
176 def __init__(self, methodName='runTest'):
177 """Create an instance of the class that will use the named test
178 method when executed. Raises a ValueError if the instance does
179 not have a method with the specified name.
180 """
181 self._testMethodName = methodName
182 self._resultForDoCleanups = None
183 try:
184 testMethod = getattr(self, methodName)
185 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000186 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000187 (self.__class__, methodName))
188 self._testMethodDoc = testMethod.__doc__
189 self._cleanups = []
190
191 # Map types to custom assertEqual functions that will compare
192 # instances of said type in more detail to generate a more useful
193 # error message.
194 self._type_equality_funcs = {}
195 self.addTypeEqualityFunc(dict, self.assertDictEqual)
196 self.addTypeEqualityFunc(list, self.assertListEqual)
197 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
198 self.addTypeEqualityFunc(set, self.assertSetEqual)
199 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foord02834952010-02-08 23:10:39 +0000200 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000201
202 def addTypeEqualityFunc(self, typeobj, function):
203 """Add a type specific assertEqual style function to compare a type.
204
205 This method is for use by TestCase subclasses that need to register
206 their own type equality functions to provide nicer error messages.
207
208 Args:
209 typeobj: The data type to call this function on when both values
210 are of the same type in assertEqual().
211 function: The callable taking two arguments and an optional
212 msg= argument that raises self.failureException with a
213 useful error message when the two arguments are not equal.
214 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000215 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000216
217 def addCleanup(self, function, *args, **kwargs):
218 """Add a function, with arguments, to be called when the test is
219 completed. Functions added are called on a LIFO basis and are
220 called after tearDown on test failure or success.
221
222 Cleanup items are called even if setUp fails (unlike tearDown)."""
223 self._cleanups.append((function, args, kwargs))
224
225 def setUp(self):
226 "Hook method for setting up the test fixture before exercising it."
227 pass
228
229 def tearDown(self):
230 "Hook method for deconstructing the test fixture after testing it."
231 pass
232
Benjamin Peterson847a4112010-03-14 15:04:17 +0000233 @classmethod
234 def setUpClass(cls):
235 "Hook method for setting up class fixture before running tests in the class."
236
237 @classmethod
238 def tearDownClass(cls):
239 "Hook method for deconstructing the class fixture after running all tests in the class."
240
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000241 def countTestCases(self):
242 return 1
243
244 def defaultTestResult(self):
245 return result.TestResult()
246
247 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000248 """Returns a one-line description of the test, or None if no
249 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000250
Michael Foord34c94622010-02-10 15:51:42 +0000251 The default implementation of this method returns the first line of
252 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000253 """
Michael Foord34c94622010-02-10 15:51:42 +0000254 doc = self._testMethodDoc
255 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000256
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000257
258 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000259 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000260
261 def __eq__(self, other):
262 if type(self) is not type(other):
263 return NotImplemented
264
265 return self._testMethodName == other._testMethodName
266
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000267 def __hash__(self):
268 return hash((type(self), self._testMethodName))
269
270 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000271 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000272
273 def __repr__(self):
274 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000275 (strclass(self.__class__), self._testMethodName)
276
277 def _addSkip(self, result, reason):
278 addSkip = getattr(result, 'addSkip', None)
279 if addSkip is not None:
280 addSkip(self, reason)
281 else:
282 warnings.warn("TestResult has no addSkip method, skips not reported",
283 RuntimeWarning, 2)
284 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000285
286 def run(self, result=None):
287 orig_result = result
288 if result is None:
289 result = self.defaultTestResult()
290 startTestRun = getattr(result, 'startTestRun', None)
291 if startTestRun is not None:
292 startTestRun()
293
294 self._resultForDoCleanups = result
295 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000296
297 testMethod = getattr(self, self._testMethodName)
298 if (getattr(self.__class__, "__unittest_skip__", False) or
299 getattr(testMethod, "__unittest_skip__", False)):
300 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000301 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000302 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
303 or getattr(testMethod, '__unittest_skip_why__', ''))
304 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000305 finally:
306 result.stopTest(self)
307 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000308 try:
309 success = False
310 try:
311 self.setUp()
312 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000313 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000314 except Exception:
315 result.addError(self, sys.exc_info())
316 else:
317 try:
318 testMethod()
319 except self.failureException:
320 result.addFailure(self, sys.exc_info())
321 except _ExpectedFailure as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000322 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
323 if addExpectedFailure is not None:
324 addExpectedFailure(self, e.exc_info)
325 else:
326 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
327 RuntimeWarning)
328 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000329 except _UnexpectedSuccess:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000330 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
331 if addUnexpectedSuccess is not None:
332 addUnexpectedSuccess(self)
333 else:
334 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
335 RuntimeWarning)
336 result.addFailure(self, sys.exc_info())
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000337 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000338 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000339 except Exception:
340 result.addError(self, sys.exc_info())
341 else:
342 success = True
343
344 try:
345 self.tearDown()
346 except Exception:
347 result.addError(self, sys.exc_info())
348 success = False
349
350 cleanUpSuccess = self.doCleanups()
351 success = success and cleanUpSuccess
352 if success:
353 result.addSuccess(self)
354 finally:
355 result.stopTest(self)
356 if orig_result is None:
357 stopTestRun = getattr(result, 'stopTestRun', None)
358 if stopTestRun is not None:
359 stopTestRun()
360
361 def doCleanups(self):
362 """Execute all cleanup functions. Normally called for you after
363 tearDown."""
364 result = self._resultForDoCleanups
365 ok = True
366 while self._cleanups:
367 function, args, kwargs = self._cleanups.pop(-1)
368 try:
369 function(*args, **kwargs)
370 except Exception:
371 ok = False
372 result.addError(self, sys.exc_info())
373 return ok
374
375 def __call__(self, *args, **kwds):
376 return self.run(*args, **kwds)
377
378 def debug(self):
379 """Run the test without collecting errors in a TestResult"""
380 self.setUp()
381 getattr(self, self._testMethodName)()
382 self.tearDown()
383
384 def skipTest(self, reason):
385 """Skip this test."""
386 raise SkipTest(reason)
387
388 def fail(self, msg=None):
389 """Fail immediately, with the given message."""
390 raise self.failureException(msg)
391
392 def assertFalse(self, expr, msg=None):
393 "Fail the test if the expression is true."
394 if expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000395 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000396 raise self.failureException(msg)
397
398 def assertTrue(self, expr, msg=None):
399 """Fail the test unless the expression is true."""
400 if not expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000401 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000402 raise self.failureException(msg)
403
404 def _formatMessage(self, msg, standardMsg):
405 """Honour the longMessage attribute when generating failure messages.
406 If longMessage is False this means:
407 * Use only an explicit message if it is provided
408 * Otherwise use the standard message for the assert
409
410 If longMessage is True:
411 * Use the standard message
412 * If an explicit message is provided, plus ' : ' and the explicit message
413 """
414 if not self.longMessage:
415 return msg or standardMsg
416 if msg is None:
417 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000418 try:
419 # don't switch to '{}' formatting in Python 2.X
420 # it changes the way unicode input is handled
421 return '%s : %s' % (standardMsg, msg)
422 except UnicodeDecodeError:
423 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000424
425
426 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
427 """Fail unless an exception of class excClass is thrown
428 by callableObj when invoked with arguments args and keyword
429 arguments kwargs. If a different type of exception is
430 thrown, it will not be caught, and the test case will be
431 deemed to have suffered an error, exactly as for an
432 unexpected exception.
433
434 If called with callableObj omitted or None, will return a
435 context object used like this::
436
Michael Foord1c42b122010-02-05 22:58:21 +0000437 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000438 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000439
440 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000441 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000442 exception after the assertion::
443
444 with self.assertRaises(SomeException) as cm:
445 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000446 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000447 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448 """
449 context = _AssertRaisesContext(excClass, self, callableObj)
450 if callableObj is None:
451 return context
452 with context:
453 callableObj(*args, **kwargs)
454
455 def _getAssertEqualityFunc(self, first, second):
456 """Get a detailed comparison function for the types of the two args.
457
458 Returns: A callable accepting (first, second, msg=None) that will
459 raise a failure exception if first != second with a useful human
460 readable error message for those types.
461 """
462 #
463 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
464 # and vice versa. I opted for the conservative approach in case
465 # subclasses are not intended to be compared in detail to their super
466 # class instances using a type equality func. This means testing
467 # subtypes won't automagically use the detailed comparison. Callers
468 # should use their type specific assertSpamEqual method to compare
469 # subclasses if the detailed comparison is desired and appropriate.
470 # See the discussion in http://bugs.python.org/issue2578.
471 #
472 if type(first) is type(second):
473 asserter = self._type_equality_funcs.get(type(first))
474 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000475 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000476
477 return self._baseAssertEqual
478
479 def _baseAssertEqual(self, first, second, msg=None):
480 """The default assertEqual implementation, not type specific."""
481 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000482 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000483 msg = self._formatMessage(msg, standardMsg)
484 raise self.failureException(msg)
485
486 def assertEqual(self, first, second, msg=None):
487 """Fail if the two objects are unequal as determined by the '=='
488 operator.
489 """
490 assertion_func = self._getAssertEqualityFunc(first, second)
491 assertion_func(first, second, msg=msg)
492
493 def assertNotEqual(self, first, second, msg=None):
494 """Fail if the two objects are equal as determined by the '=='
495 operator.
496 """
497 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000498 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
499 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000500 raise self.failureException(msg)
501
Benjamin Petersonb48af542010-04-11 20:43:16 +0000502 def assertAlmostEqual(self, first, second, *, places=None, msg=None,
503 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504 """Fail if the two objects are unequal as determined by their
505 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000506 (default 7) and comparing to zero, or by comparing that the
507 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000508
509 Note that decimal places (from zero) are usually not the same
510 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000511
512 If the two objects compare equal then they will automatically
513 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000514 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000515 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000516 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000517 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000518 if delta is not None and places is not None:
519 raise TypeError("specify delta or places not both")
520
521 if delta is not None:
522 if abs(first - second) <= delta:
523 return
524
525 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
526 safe_repr(second),
527 safe_repr(delta))
528 else:
529 if places is None:
530 places = 7
531
532 if round(abs(second-first), places) == 0:
533 return
534
Benjamin Peterson847a4112010-03-14 15:04:17 +0000535 standardMsg = '%s != %s within %r places' % (safe_repr(first),
536 safe_repr(second),
537 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000538 msg = self._formatMessage(msg, standardMsg)
539 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000540
Benjamin Petersonb48af542010-04-11 20:43:16 +0000541 def assertNotAlmostEqual(self, first, second, *, places=None, msg=None,
542 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000543 """Fail if the two objects are equal as determined by their
544 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000545 (default 7) and comparing to zero, or by comparing that the
546 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000547
548 Note that decimal places (from zero) are usually not the same
549 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000550
551 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000552 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000553 if delta is not None and places is not None:
554 raise TypeError("specify delta or places not both")
555 if delta is not None:
556 if not (first == second) and abs(first - second) > delta:
557 return
558 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
559 safe_repr(second),
560 safe_repr(delta))
561 else:
562 if places is None:
563 places = 7
564 if not (first == second) and round(abs(second-first), places) != 0:
565 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000566 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000567 safe_repr(second),
568 places)
569
570 msg = self._formatMessage(msg, standardMsg)
571 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000572
573 # Synonyms for assertion methods
574
575 # The plurals are undocumented. Keep them that way to discourage use.
576 # Do not add more. Do not remove.
577 # Going through a deprecation cycle on these would annoy many people.
578 assertEquals = assertEqual
579 assertNotEquals = assertNotEqual
580 assertAlmostEquals = assertAlmostEqual
581 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord0e31b992010-02-10 15:52:56 +0000582 assert_ = assertTrue
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000583
584 # These fail* assertion method names are pending deprecation and will
585 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
586 def _deprecate(original_func):
587 def deprecated_func(*args, **kwargs):
588 warnings.warn(
589 'Please use {0} instead.'.format(original_func.__name__),
590 DeprecationWarning, 2)
591 return original_func(*args, **kwargs)
592 return deprecated_func
593
594 failUnlessEqual = _deprecate(assertEqual)
595 failIfEqual = _deprecate(assertNotEqual)
596 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
597 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
598 failUnless = _deprecate(assertTrue)
599 failUnlessRaises = _deprecate(assertRaises)
600 failIf = _deprecate(assertFalse)
601
Michael Foord2034d9a2010-06-05 11:27:52 +0000602 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None,
603 max_diff=80*8):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000604 """An equality assertion for ordered sequences (like lists and tuples).
605
R. David Murrayad13f222010-01-29 22:17:58 +0000606 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000607 which can be indexed, has a length, and has an equality operator.
608
609 Args:
610 seq1: The first sequence to compare.
611 seq2: The second sequence to compare.
612 seq_type: The expected datatype of the sequences, or None if no
613 datatype should be enforced.
614 msg: Optional message to use on failure instead of a list of
615 differences.
Michael Foord2034d9a2010-06-05 11:27:52 +0000616 max_diff: Maximum size off the diff, larger diffs are not shown
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000617 """
618 if seq_type != None:
619 seq_type_name = seq_type.__name__
620 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000621 raise self.failureException('First sequence is not a %s: %s'
622 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000623 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000624 raise self.failureException('Second sequence is not a %s: %s'
625 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000626 else:
627 seq_type_name = "sequence"
628
629 differing = None
630 try:
631 len1 = len(seq1)
632 except (TypeError, NotImplementedError):
633 differing = 'First %s has no length. Non-sequence?' % (
634 seq_type_name)
635
636 if differing is None:
637 try:
638 len2 = len(seq2)
639 except (TypeError, NotImplementedError):
640 differing = 'Second %s has no length. Non-sequence?' % (
641 seq_type_name)
642
643 if differing is None:
644 if seq1 == seq2:
645 return
646
Benjamin Peterson847a4112010-03-14 15:04:17 +0000647 seq1_repr = safe_repr(seq1)
648 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000649 if len(seq1_repr) > 30:
650 seq1_repr = seq1_repr[:30] + '...'
651 if len(seq2_repr) > 30:
652 seq2_repr = seq2_repr[:30] + '...'
653 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
654 differing = '%ss differ: %s != %s\n' % elements
655
656 for i in range(min(len1, len2)):
657 try:
658 item1 = seq1[i]
659 except (TypeError, IndexError, NotImplementedError):
660 differing += ('\nUnable to index element %d of first %s\n' %
661 (i, seq_type_name))
662 break
663
664 try:
665 item2 = seq2[i]
666 except (TypeError, IndexError, NotImplementedError):
667 differing += ('\nUnable to index element %d of second %s\n' %
668 (i, seq_type_name))
669 break
670
671 if item1 != item2:
672 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
673 (i, item1, item2))
674 break
675 else:
676 if (len1 == len2 and seq_type is None and
677 type(seq1) != type(seq2)):
678 # The sequences are the same, but have differing types.
679 return
680
681 if len1 > len2:
682 differing += ('\nFirst %s contains %d additional '
683 'elements.\n' % (seq_type_name, len1 - len2))
684 try:
685 differing += ('First extra element %d:\n%s\n' %
686 (len2, seq1[len2]))
687 except (TypeError, IndexError, NotImplementedError):
688 differing += ('Unable to index element %d '
689 'of first %s\n' % (len2, seq_type_name))
690 elif len1 < len2:
691 differing += ('\nSecond %s contains %d additional '
692 'elements.\n' % (seq_type_name, len2 - len1))
693 try:
694 differing += ('First extra element %d:\n%s\n' %
695 (len1, seq2[len1]))
696 except (TypeError, IndexError, NotImplementedError):
697 differing += ('Unable to index element %d '
698 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000699 standardMsg = differing
700 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000701 difflib.ndiff(pprint.pformat(seq1).splitlines(),
702 pprint.pformat(seq2).splitlines()))
Michael Foord2034d9a2010-06-05 11:27:52 +0000703 if max_diff is None or len(diffMsg) <= max_diff:
704 standardMsg += diffMsg
705 else:
706 standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000707 msg = self._formatMessage(msg, standardMsg)
708 self.fail(msg)
709
710 def assertListEqual(self, list1, list2, msg=None):
711 """A list-specific equality assertion.
712
713 Args:
714 list1: The first list to compare.
715 list2: The second list to compare.
716 msg: Optional message to use on failure instead of a list of
717 differences.
718
719 """
720 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
721
722 def assertTupleEqual(self, tuple1, tuple2, msg=None):
723 """A tuple-specific equality assertion.
724
725 Args:
726 tuple1: The first tuple to compare.
727 tuple2: The second tuple to compare.
728 msg: Optional message to use on failure instead of a list of
729 differences.
730 """
731 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
732
733 def assertSetEqual(self, set1, set2, msg=None):
734 """A set-specific equality assertion.
735
736 Args:
737 set1: The first set to compare.
738 set2: The second set to compare.
739 msg: Optional message to use on failure instead of a list of
740 differences.
741
Michael Foord91c9da32010-03-20 17:21:27 +0000742 assertSetEqual uses ducktyping to support different types of sets, and
743 is optimized for sets specifically (parameters must support a
744 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000745 """
746 try:
747 difference1 = set1.difference(set2)
748 except TypeError as e:
749 self.fail('invalid type when attempting set difference: %s' % e)
750 except AttributeError as e:
751 self.fail('first argument does not support set difference: %s' % e)
752
753 try:
754 difference2 = set2.difference(set1)
755 except TypeError as e:
756 self.fail('invalid type when attempting set difference: %s' % e)
757 except AttributeError as e:
758 self.fail('second argument does not support set difference: %s' % e)
759
760 if not (difference1 or difference2):
761 return
762
763 lines = []
764 if difference1:
765 lines.append('Items in the first set but not the second:')
766 for item in difference1:
767 lines.append(repr(item))
768 if difference2:
769 lines.append('Items in the second set but not the first:')
770 for item in difference2:
771 lines.append(repr(item))
772
773 standardMsg = '\n'.join(lines)
774 self.fail(self._formatMessage(msg, standardMsg))
775
776 def assertIn(self, member, container, msg=None):
777 """Just like self.assertTrue(a in b), but with a nicer default message."""
778 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000779 standardMsg = '%s not found in %s' % (safe_repr(member),
780 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000781 self.fail(self._formatMessage(msg, standardMsg))
782
783 def assertNotIn(self, member, container, msg=None):
784 """Just like self.assertTrue(a not in b), but with a nicer default message."""
785 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000786 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
787 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000788 self.fail(self._formatMessage(msg, standardMsg))
789
790 def assertIs(self, expr1, expr2, msg=None):
791 """Just like self.assertTrue(a is b), but with a nicer default message."""
792 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000793 standardMsg = '%s is not %s' % (safe_repr(expr1),
794 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000795 self.fail(self._formatMessage(msg, standardMsg))
796
797 def assertIsNot(self, expr1, expr2, msg=None):
798 """Just like self.assertTrue(a is not b), but with a nicer default message."""
799 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000800 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000801 self.fail(self._formatMessage(msg, standardMsg))
802
803 def assertDictEqual(self, d1, d2, msg=None):
804 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
805 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
806
807 if d1 != d2:
808 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
809 pprint.pformat(d1).splitlines(),
810 pprint.pformat(d2).splitlines())))
811 self.fail(self._formatMessage(msg, standardMsg))
812
813 def assertDictContainsSubset(self, expected, actual, msg=None):
814 """Checks whether actual is a superset of expected."""
815 missing = []
816 mismatched = []
817 for key, value in expected.items():
818 if key not in actual:
819 missing.append(key)
820 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000821 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000822 (safe_repr(key), safe_repr(value),
823 safe_repr(actual[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000824
825 if not (missing or mismatched):
826 return
827
828 standardMsg = ''
829 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000830 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
831 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000832 if mismatched:
833 if standardMsg:
834 standardMsg += '; '
835 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
836
837 self.fail(self._formatMessage(msg, standardMsg))
838
839 def assertSameElements(self, expected_seq, actual_seq, msg=None):
840 """An unordered sequence specific comparison.
841
842 Raises with an error message listing which elements of expected_seq
843 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000844
845 Duplicate elements are ignored when comparing *expected_seq* and
846 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
847 set(actual))`` but it works with sequences of unhashable objects as
848 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000849 """
Michael Foord91c9da32010-03-20 17:21:27 +0000850 warnings.warn('assertSameElements is deprecated',
851 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000852 try:
853 expected = set(expected_seq)
854 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000855 missing = sorted(expected.difference(actual))
856 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000857 except TypeError:
858 # Fall back to slower list-compare if any of the objects are
859 # not hashable.
860 expected = list(expected_seq)
861 actual = list(actual_seq)
862 try:
863 expected.sort()
864 actual.sort()
865 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000866 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000867 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000868 else:
869 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000870 errors = []
871 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000872 errors.append('Expected, but missing:\n %s' %
873 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000874 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000875 errors.append('Unexpected, but present:\n %s' %
876 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000877 if errors:
878 standardMsg = '\n'.join(errors)
879 self.fail(self._formatMessage(msg, standardMsg))
880
Michael Foord8442a602010-03-20 16:58:04 +0000881
882 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
883 """An unordered sequence / set specific comparison. It asserts that
884 expected_seq and actual_seq contain the same elements. It is
885 the equivalent of::
886
887 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
888
889 Raises with an error message listing which elements of expected_seq
890 are missing from actual_seq and vice versa if any.
891
892 Asserts that each element has the same count in both sequences.
893 Example:
894 - [0, 1, 1] and [1, 0, 1] compare equal.
895 - [0, 0, 1] and [0, 1] compare unequal.
896 """
897 try:
898 expected = sorted(expected_seq)
899 actual = sorted(actual_seq)
900 except TypeError:
901 # Unsortable items (example: set(), complex(), ...)
902 expected = list(expected_seq)
903 actual = list(actual_seq)
904 missing, unexpected = unorderable_list_difference(expected, actual)
905 else:
906 return self.assertSequenceEqual(expected, actual, msg=msg)
907
908 errors = []
909 if missing:
910 errors.append('Expected, but missing:\n %s' %
911 safe_repr(missing))
912 if unexpected:
913 errors.append('Unexpected, but present:\n %s' %
914 safe_repr(unexpected))
915 if errors:
916 standardMsg = '\n'.join(errors)
917 self.fail(self._formatMessage(msg, standardMsg))
918
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000919 def assertMultiLineEqual(self, first, second, msg=None):
920 """Assert that two multi-line strings are equal."""
921 self.assert_(isinstance(first, str), (
922 'First argument is not a string'))
923 self.assert_(isinstance(second, str), (
924 'Second argument is not a string'))
925
926 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000927 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
928 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000929 self.fail(self._formatMessage(msg, standardMsg))
930
931 def assertLess(self, a, b, msg=None):
932 """Just like self.assertTrue(a < b), but with a nicer default message."""
933 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000934 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000935 self.fail(self._formatMessage(msg, standardMsg))
936
937 def assertLessEqual(self, a, b, msg=None):
938 """Just like self.assertTrue(a <= b), but with a nicer default message."""
939 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000940 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000941 self.fail(self._formatMessage(msg, standardMsg))
942
943 def assertGreater(self, a, b, msg=None):
944 """Just like self.assertTrue(a > b), but with a nicer default message."""
945 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000946 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000947 self.fail(self._formatMessage(msg, standardMsg))
948
949 def assertGreaterEqual(self, a, b, msg=None):
950 """Just like self.assertTrue(a >= b), but with a nicer default message."""
951 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000952 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000953 self.fail(self._formatMessage(msg, standardMsg))
954
955 def assertIsNone(self, obj, msg=None):
956 """Same as self.assertTrue(obj is None), with a nicer default message."""
957 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000958 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000959 self.fail(self._formatMessage(msg, standardMsg))
960
961 def assertIsNotNone(self, obj, msg=None):
962 """Included for symmetry with assertIsNone."""
963 if obj is None:
964 standardMsg = 'unexpectedly None'
965 self.fail(self._formatMessage(msg, standardMsg))
966
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000967 def assertIsInstance(self, obj, cls, msg=None):
968 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
969 default message."""
970 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000971 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000972 self.fail(self._formatMessage(msg, standardMsg))
973
974 def assertNotIsInstance(self, obj, cls, msg=None):
975 """Included for symmetry with assertIsInstance."""
976 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000977 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000978 self.fail(self._formatMessage(msg, standardMsg))
979
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000980 def assertRaisesRegexp(self, expected_exception, expected_regexp,
981 callable_obj=None, *args, **kwargs):
982 """Asserts that the message in a raised exception matches a regexp.
983
984 Args:
985 expected_exception: Exception class expected to be raised.
986 expected_regexp: Regexp (re pattern object or string) expected
987 to be found in error message.
988 callable_obj: Function to be called.
989 args: Extra args.
990 kwargs: Extra kwargs.
991 """
992 context = _AssertRaisesContext(expected_exception, self, callable_obj,
993 expected_regexp)
994 if callable_obj is None:
995 return context
996 with context:
997 callable_obj(*args, **kwargs)
998
Georg Brandl89fad142010-03-14 10:23:39 +0000999 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001000 """Fail the test unless the text matches the regular expression."""
Georg Brandl89fad142010-03-14 10:23:39 +00001001 if isinstance(expected_regexp, (str, bytes)):
1002 expected_regexp = re.compile(expected_regexp)
1003 if not expected_regexp.search(text):
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001004 msg = msg or "Regexp didn't match"
Georg Brandl89fad142010-03-14 10:23:39 +00001005 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001006 raise self.failureException(msg)
1007
Benjamin Petersonb48af542010-04-11 20:43:16 +00001008 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001009 """Fail the test if the text matches the regular expression."""
Benjamin Petersonb48af542010-04-11 20:43:16 +00001010 if isinstance(unexpected_regexp, (str, bytes)):
1011 unexpected_regexp = re.compile(unexpected_regexp)
1012 match = unexpected_regexp.search(text)
1013 if match:
1014 msg = msg or "Regexp matched"
1015 msg = '%s: %r matches %r in %r' % (msg,
1016 text[match.start():match.end()],
1017 unexpected_regexp.pattern,
1018 text)
1019 raise self.failureException(msg)
1020
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001021
1022class FunctionTestCase(TestCase):
1023 """A test case that wraps a test function.
1024
1025 This is useful for slipping pre-existing test functions into the
1026 unittest framework. Optionally, set-up and tidy-up functions can be
1027 supplied. As with TestCase, the tidy-up ('tearDown') function will
1028 always be called if the set-up ('setUp') function ran successfully.
1029 """
1030
1031 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1032 super(FunctionTestCase, self).__init__()
1033 self._setUpFunc = setUp
1034 self._tearDownFunc = tearDown
1035 self._testFunc = testFunc
1036 self._description = description
1037
1038 def setUp(self):
1039 if self._setUpFunc is not None:
1040 self._setUpFunc()
1041
1042 def tearDown(self):
1043 if self._tearDownFunc is not None:
1044 self._tearDownFunc()
1045
1046 def runTest(self):
1047 self._testFunc()
1048
1049 def id(self):
1050 return self._testFunc.__name__
1051
1052 def __eq__(self, other):
1053 if not isinstance(other, self.__class__):
1054 return NotImplemented
1055
1056 return self._setUpFunc == other._setUpFunc and \
1057 self._tearDownFunc == other._tearDownFunc and \
1058 self._testFunc == other._testFunc and \
1059 self._description == other._description
1060
1061 def __ne__(self, other):
1062 return not self == other
1063
1064 def __hash__(self):
1065 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1066 self._testFunc, self._description))
1067
1068 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001069 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001070 self._testFunc.__name__)
1071
1072 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001073 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001074 self._testFunc)
1075
1076 def shortDescription(self):
1077 if self._description is not None:
1078 return self._description
1079 doc = self._testFunc.__doc__
1080 return doc and doc.split("\n")[0].strip() or None