blob: de589685c3f47bc0f839862af33bb5ce0ab0b558 [file] [log] [blame]
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001"""Test case implementation"""
2
3import sys
4import functools
5import difflib
6import pprint
7import re
8import warnings
9
Michael Foord225a0992010-02-18 20:30:09 +000010from . import result
Michael Foord98e7b762010-03-20 03:00:34 +000011from .util import (
12 strclass, safe_repr, sorted_list_difference, unorderable_list_difference
13)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000014
Michael Foordb1aa30f2010-03-22 00:06:30 +000015__unittest = True
Michael Foord01007022010-06-05 11:23:51 +000016TRUNCATED_DIFF = '\n[diff truncated...]'
Michael Foordb1aa30f2010-03-22 00:06:30 +000017
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000018class SkipTest(Exception):
19 """
20 Raise this exception in a test to skip it.
21
22 Usually you can use TestResult.skip() or one of the skipping decorators
23 instead of raising this directly.
24 """
25 pass
26
27class _ExpectedFailure(Exception):
28 """
29 Raise this when a test is expected to fail.
30
31 This is an implementation detail.
32 """
33
34 def __init__(self, exc_info):
35 super(_ExpectedFailure, self).__init__()
36 self.exc_info = exc_info
37
38class _UnexpectedSuccess(Exception):
39 """
40 The test was supposed to fail, but it didn't!
41 """
42 pass
43
44def _id(obj):
45 return obj
46
47def skip(reason):
48 """
49 Unconditionally skip a test.
50 """
51 def decorator(test_item):
Michael Foord53e8eea2010-03-07 20:22:12 +000052 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
53 @functools.wraps(test_item)
54 def skip_wrapper(*args, **kwargs):
55 raise SkipTest(reason)
56 test_item = skip_wrapper
57
58 test_item.__unittest_skip__ = True
59 test_item.__unittest_skip_why__ = reason
60 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000061 return decorator
62
63def skipIf(condition, reason):
64 """
65 Skip a test if the condition is true.
66 """
67 if condition:
68 return skip(reason)
69 return _id
70
71def skipUnless(condition, reason):
72 """
73 Skip a test unless the condition is true.
74 """
75 if not condition:
76 return skip(reason)
77 return _id
78
79
80def expectedFailure(func):
81 @functools.wraps(func)
82 def wrapper(*args, **kwargs):
83 try:
84 func(*args, **kwargs)
85 except Exception:
86 raise _ExpectedFailure(sys.exc_info())
87 raise _UnexpectedSuccess
88 return wrapper
89
90
91class _AssertRaisesContext(object):
92 """A context manager used to implement TestCase.assertRaises* methods."""
93
94 def __init__(self, expected, test_case, expected_regexp=None):
95 self.expected = expected
96 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +000097 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000098
99 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +0000100 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000101
102 def __exit__(self, exc_type, exc_value, tb):
103 if exc_type is None:
104 try:
105 exc_name = self.expected.__name__
106 except AttributeError:
107 exc_name = str(self.expected)
108 raise self.failureException(
109 "{0} not raised".format(exc_name))
110 if not issubclass(exc_type, self.expected):
111 # let unexpected exceptions pass through
112 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000113 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000114 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000115 return True
116
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000117 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000118 if isinstance(expected_regexp, basestring):
119 expected_regexp = re.compile(expected_regexp)
120 if not expected_regexp.search(str(exc_value)):
121 raise self.failureException('"%s" does not match "%s"' %
122 (expected_regexp.pattern, str(exc_value)))
123 return True
124
125
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000126class TestCase(object):
127 """A class whose instances are single test cases.
128
129 By default, the test code itself should be placed in a method named
130 'runTest'.
131
132 If the fixture may be used for many test cases, create as
133 many test methods as are needed. When instantiating such a TestCase
134 subclass, specify in the constructor arguments the name of the test method
135 that the instance is to execute.
136
137 Test authors should subclass TestCase for their own tests. Construction
138 and deconstruction of the test's environment ('fixture') can be
139 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
140
141 If it is necessary to override the __init__ method, the base class
142 __init__ method must always be called. It is important that subclasses
143 should not change the signature of their __init__ method, since instances
144 of the classes are instantiated automatically by parts of the framework
145 in order to be run.
146 """
147
148 # This attribute determines which exception will be raised when
149 # the instance's assertion methods fail; test methods raising this
150 # exception will be deemed to have 'failed' rather than 'errored'
151
152 failureException = AssertionError
153
154 # This attribute determines whether long messages (including repr of
155 # objects used in assert methods) will be printed on failure in *addition*
156 # to any explicit message passed.
157
158 longMessage = False
159
Michael Foord5ffa3252010-03-07 22:04:55 +0000160 # Attribute used by TestSuite for classSetUp
161
162 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000163
164 def __init__(self, methodName='runTest'):
165 """Create an instance of the class that will use the named test
166 method when executed. Raises a ValueError if the instance does
167 not have a method with the specified name.
168 """
169 self._testMethodName = methodName
170 self._resultForDoCleanups = None
171 try:
172 testMethod = getattr(self, methodName)
173 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000174 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000175 (self.__class__, methodName))
176 self._testMethodDoc = testMethod.__doc__
177 self._cleanups = []
178
179 # Map types to custom assertEqual functions that will compare
180 # instances of said type in more detail to generate a more useful
181 # error message.
182 self._type_equality_funcs = {}
183 self.addTypeEqualityFunc(dict, self.assertDictEqual)
184 self.addTypeEqualityFunc(list, self.assertListEqual)
185 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
186 self.addTypeEqualityFunc(set, self.assertSetEqual)
187 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foordfe6349c2010-02-08 22:41:16 +0000188 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000189
190 def addTypeEqualityFunc(self, typeobj, function):
191 """Add a type specific assertEqual style function to compare a type.
192
193 This method is for use by TestCase subclasses that need to register
194 their own type equality functions to provide nicer error messages.
195
196 Args:
197 typeobj: The data type to call this function on when both values
198 are of the same type in assertEqual().
199 function: The callable taking two arguments and an optional
200 msg= argument that raises self.failureException with a
201 useful error message when the two arguments are not equal.
202 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000203 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000204
205 def addCleanup(self, function, *args, **kwargs):
206 """Add a function, with arguments, to be called when the test is
207 completed. Functions added are called on a LIFO basis and are
208 called after tearDown on test failure or success.
209
210 Cleanup items are called even if setUp fails (unlike tearDown)."""
211 self._cleanups.append((function, args, kwargs))
212
213 def setUp(self):
214 "Hook method for setting up the test fixture before exercising it."
215 pass
216
217 def tearDown(self):
218 "Hook method for deconstructing the test fixture after testing it."
219 pass
220
Michael Foord5ffa3252010-03-07 22:04:55 +0000221 @classmethod
222 def setUpClass(cls):
223 "Hook method for setting up class fixture before running tests in the class."
224
225 @classmethod
226 def tearDownClass(cls):
227 "Hook method for deconstructing the class fixture after running all tests in the class."
228
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000229 def countTestCases(self):
230 return 1
231
232 def defaultTestResult(self):
233 return result.TestResult()
234
235 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000236 """Returns a one-line description of the test, or None if no
237 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000238
Michael Foorddb43b5a2010-02-10 14:25:12 +0000239 The default implementation of this method returns the first line of
240 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000241 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000242 doc = self._testMethodDoc
243 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000244
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000245
246 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000247 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000248
249 def __eq__(self, other):
250 if type(self) is not type(other):
251 return NotImplemented
252
253 return self._testMethodName == other._testMethodName
254
255 def __ne__(self, other):
256 return not self == other
257
258 def __hash__(self):
259 return hash((type(self), self._testMethodName))
260
261 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000262 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000263
264 def __repr__(self):
265 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000266 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000267
Michael Foordae3db0a2010-02-22 23:28:32 +0000268 def _addSkip(self, result, reason):
269 addSkip = getattr(result, 'addSkip', None)
270 if addSkip is not None:
271 addSkip(self, reason)
272 else:
273 warnings.warn("TestResult has no addSkip method, skips not reported",
274 RuntimeWarning, 2)
275 result.addSuccess(self)
276
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000277 def run(self, result=None):
278 orig_result = result
279 if result is None:
280 result = self.defaultTestResult()
281 startTestRun = getattr(result, 'startTestRun', None)
282 if startTestRun is not None:
283 startTestRun()
284
285 self._resultForDoCleanups = result
286 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000287
288 testMethod = getattr(self, self._testMethodName)
289 if (getattr(self.__class__, "__unittest_skip__", False) or
290 getattr(testMethod, "__unittest_skip__", False)):
291 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000292 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000293 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
294 or getattr(testMethod, '__unittest_skip_why__', ''))
295 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000296 finally:
297 result.stopTest(self)
298 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000299 try:
300 success = False
301 try:
302 self.setUp()
303 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000304 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000305 except Exception:
306 result.addError(self, sys.exc_info())
307 else:
308 try:
309 testMethod()
310 except self.failureException:
311 result.addFailure(self, sys.exc_info())
312 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000313 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
314 if addExpectedFailure is not None:
315 addExpectedFailure(self, e.exc_info)
316 else:
317 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
318 RuntimeWarning)
319 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000320 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000321 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
322 if addUnexpectedSuccess is not None:
323 addUnexpectedSuccess(self)
324 else:
325 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
326 RuntimeWarning)
327 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000328 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000329 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000330 except Exception:
331 result.addError(self, sys.exc_info())
332 else:
333 success = True
334
335 try:
336 self.tearDown()
337 except Exception:
338 result.addError(self, sys.exc_info())
339 success = False
340
341 cleanUpSuccess = self.doCleanups()
342 success = success and cleanUpSuccess
343 if success:
344 result.addSuccess(self)
345 finally:
346 result.stopTest(self)
347 if orig_result is None:
348 stopTestRun = getattr(result, 'stopTestRun', None)
349 if stopTestRun is not None:
350 stopTestRun()
351
352 def doCleanups(self):
353 """Execute all cleanup functions. Normally called for you after
354 tearDown."""
355 result = self._resultForDoCleanups
356 ok = True
357 while self._cleanups:
358 function, args, kwargs = self._cleanups.pop(-1)
359 try:
360 function(*args, **kwargs)
361 except Exception:
362 ok = False
363 result.addError(self, sys.exc_info())
364 return ok
365
366 def __call__(self, *args, **kwds):
367 return self.run(*args, **kwds)
368
369 def debug(self):
370 """Run the test without collecting errors in a TestResult"""
371 self.setUp()
372 getattr(self, self._testMethodName)()
373 self.tearDown()
374
375 def skipTest(self, reason):
376 """Skip this test."""
377 raise SkipTest(reason)
378
379 def fail(self, msg=None):
380 """Fail immediately, with the given message."""
381 raise self.failureException(msg)
382
383 def assertFalse(self, expr, msg=None):
384 "Fail the test if the expression is true."
385 if expr:
Michael Foord225a0992010-02-18 20:30:09 +0000386 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000387 raise self.failureException(msg)
388
389 def assertTrue(self, expr, msg=None):
390 """Fail the test unless the expression is true."""
391 if not expr:
Michael Foord225a0992010-02-18 20:30:09 +0000392 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000393 raise self.failureException(msg)
394
395 def _formatMessage(self, msg, standardMsg):
396 """Honour the longMessage attribute when generating failure messages.
397 If longMessage is False this means:
398 * Use only an explicit message if it is provided
399 * Otherwise use the standard message for the assert
400
401 If longMessage is True:
402 * Use the standard message
403 * If an explicit message is provided, plus ' : ' and the explicit message
404 """
405 if not self.longMessage:
406 return msg or standardMsg
407 if msg is None:
408 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000409 try:
410 # don't switch to '{}' formatting in Python 2.X
411 # it changes the way unicode input is handled
412 return '%s : %s' % (standardMsg, msg)
413 except UnicodeDecodeError:
414 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000415
416
417 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
418 """Fail unless an exception of class excClass is thrown
419 by callableObj when invoked with arguments args and keyword
420 arguments kwargs. If a different type of exception is
421 thrown, it will not be caught, and the test case will be
422 deemed to have suffered an error, exactly as for an
423 unexpected exception.
424
425 If called with callableObj omitted or None, will return a
426 context object used like this::
427
Michael Foordd0edec32010-02-05 22:55:09 +0000428 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000429 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000430
431 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000432 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000433 exception after the assertion::
434
435 with self.assertRaises(SomeException) as cm:
436 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000437 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000438 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000439 """
440 context = _AssertRaisesContext(excClass, self)
441 if callableObj is None:
442 return context
443 with context:
444 callableObj(*args, **kwargs)
445
446 def _getAssertEqualityFunc(self, first, second):
447 """Get a detailed comparison function for the types of the two args.
448
449 Returns: A callable accepting (first, second, msg=None) that will
450 raise a failure exception if first != second with a useful human
451 readable error message for those types.
452 """
453 #
454 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
455 # and vice versa. I opted for the conservative approach in case
456 # subclasses are not intended to be compared in detail to their super
457 # class instances using a type equality func. This means testing
458 # subtypes won't automagically use the detailed comparison. Callers
459 # should use their type specific assertSpamEqual method to compare
460 # subclasses if the detailed comparison is desired and appropriate.
461 # See the discussion in http://bugs.python.org/issue2578.
462 #
463 if type(first) is type(second):
464 asserter = self._type_equality_funcs.get(type(first))
465 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000466 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000467
468 return self._baseAssertEqual
469
470 def _baseAssertEqual(self, first, second, msg=None):
471 """The default assertEqual implementation, not type specific."""
472 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000473 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000474 msg = self._formatMessage(msg, standardMsg)
475 raise self.failureException(msg)
476
477 def assertEqual(self, first, second, msg=None):
478 """Fail if the two objects are unequal as determined by the '=='
479 operator.
480 """
481 assertion_func = self._getAssertEqualityFunc(first, second)
482 assertion_func(first, second, msg=msg)
483
484 def assertNotEqual(self, first, second, msg=None):
485 """Fail if the two objects are equal as determined by the '=='
486 operator.
487 """
488 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000489 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
490 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000491 raise self.failureException(msg)
492
Michael Foorda7e08fe2010-03-27 19:10:11 +0000493
494 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000495 """Fail if the two objects are unequal as determined by their
496 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000497 (default 7) and comparing to zero, or by comparing that the
498 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000499
500 Note that decimal places (from zero) are usually not the same
501 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000502
503 If the two objects compare equal then they will automatically
504 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000505 """
Michael Foordc3f79372009-09-13 16:40:02 +0000506 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000507 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000508 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000509 if delta is not None and places is not None:
510 raise TypeError("specify delta or places not both")
511
512 if delta is not None:
513 if abs(first - second) <= delta:
514 return
515
516 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
517 safe_repr(second),
518 safe_repr(delta))
519 else:
520 if places is None:
521 places = 7
522
523 if round(abs(second-first), places) == 0:
524 return
525
Michael Foord225a0992010-02-18 20:30:09 +0000526 standardMsg = '%s != %s within %r places' % (safe_repr(first),
527 safe_repr(second),
528 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000529 msg = self._formatMessage(msg, standardMsg)
530 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000531
Michael Foorda7e08fe2010-03-27 19:10:11 +0000532 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000533 """Fail if the two objects are equal as determined by their
534 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000535 (default 7) and comparing to zero, or by comparing that the
536 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000537
538 Note that decimal places (from zero) are usually not the same
539 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000540
541 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000542 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000543 if delta is not None and places is not None:
544 raise TypeError("specify delta or places not both")
545 if delta is not None:
546 if not (first == second) and abs(first - second) > delta:
547 return
548 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
549 safe_repr(second),
550 safe_repr(delta))
551 else:
552 if places is None:
553 places = 7
554 if not (first == second) and round(abs(second-first), places) != 0:
555 return
Michael Foord225a0992010-02-18 20:30:09 +0000556 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000557 safe_repr(second),
558 places)
559
560 msg = self._formatMessage(msg, standardMsg)
561 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000562
563 # Synonyms for assertion methods
564
565 # The plurals are undocumented. Keep them that way to discourage use.
566 # Do not add more. Do not remove.
567 # Going through a deprecation cycle on these would annoy many people.
568 assertEquals = assertEqual
569 assertNotEquals = assertNotEqual
570 assertAlmostEquals = assertAlmostEqual
571 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000572 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000573
574 # These fail* assertion method names are pending deprecation and will
575 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
576 def _deprecate(original_func):
577 def deprecated_func(*args, **kwargs):
578 warnings.warn(
579 'Please use {0} instead.'.format(original_func.__name__),
580 PendingDeprecationWarning, 2)
581 return original_func(*args, **kwargs)
582 return deprecated_func
583
584 failUnlessEqual = _deprecate(assertEqual)
585 failIfEqual = _deprecate(assertNotEqual)
586 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
587 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
588 failUnless = _deprecate(assertTrue)
589 failUnlessRaises = _deprecate(assertRaises)
590 failIf = _deprecate(assertFalse)
591
Michael Foord01007022010-06-05 11:23:51 +0000592 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None,
593 max_diff=80*8):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000594 """An equality assertion for ordered sequences (like lists and tuples).
595
R. David Murray05b41712010-01-29 19:35:39 +0000596 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000597 which can be indexed, has a length, and has an equality operator.
598
599 Args:
600 seq1: The first sequence to compare.
601 seq2: The second sequence to compare.
602 seq_type: The expected datatype of the sequences, or None if no
603 datatype should be enforced.
604 msg: Optional message to use on failure instead of a list of
605 differences.
Michael Foord01007022010-06-05 11:23:51 +0000606 max_diff: Maximum size off the diff, larger diffs are not shown
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000607 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000608 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000609 seq_type_name = seq_type.__name__
610 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000611 raise self.failureException('First sequence is not a %s: %s'
612 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000613 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000614 raise self.failureException('Second sequence is not a %s: %s'
615 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000616 else:
617 seq_type_name = "sequence"
618
619 differing = None
620 try:
621 len1 = len(seq1)
622 except (TypeError, NotImplementedError):
623 differing = 'First %s has no length. Non-sequence?' % (
624 seq_type_name)
625
626 if differing is None:
627 try:
628 len2 = len(seq2)
629 except (TypeError, NotImplementedError):
630 differing = 'Second %s has no length. Non-sequence?' % (
631 seq_type_name)
632
633 if differing is None:
634 if seq1 == seq2:
635 return
636
Michael Foord225a0992010-02-18 20:30:09 +0000637 seq1_repr = safe_repr(seq1)
638 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000639 if len(seq1_repr) > 30:
640 seq1_repr = seq1_repr[:30] + '...'
641 if len(seq2_repr) > 30:
642 seq2_repr = seq2_repr[:30] + '...'
643 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
644 differing = '%ss differ: %s != %s\n' % elements
645
646 for i in xrange(min(len1, len2)):
647 try:
648 item1 = seq1[i]
649 except (TypeError, IndexError, NotImplementedError):
650 differing += ('\nUnable to index element %d of first %s\n' %
651 (i, seq_type_name))
652 break
653
654 try:
655 item2 = seq2[i]
656 except (TypeError, IndexError, NotImplementedError):
657 differing += ('\nUnable to index element %d of second %s\n' %
658 (i, seq_type_name))
659 break
660
661 if item1 != item2:
662 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
663 (i, item1, item2))
664 break
665 else:
666 if (len1 == len2 and seq_type is None and
667 type(seq1) != type(seq2)):
668 # The sequences are the same, but have differing types.
669 return
670
671 if len1 > len2:
672 differing += ('\nFirst %s contains %d additional '
673 'elements.\n' % (seq_type_name, len1 - len2))
674 try:
675 differing += ('First extra element %d:\n%s\n' %
676 (len2, seq1[len2]))
677 except (TypeError, IndexError, NotImplementedError):
678 differing += ('Unable to index element %d '
679 'of first %s\n' % (len2, seq_type_name))
680 elif len1 < len2:
681 differing += ('\nSecond %s contains %d additional '
682 'elements.\n' % (seq_type_name, len2 - len1))
683 try:
684 differing += ('First extra element %d:\n%s\n' %
685 (len1, seq2[len1]))
686 except (TypeError, IndexError, NotImplementedError):
687 differing += ('Unable to index element %d '
688 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000689 standardMsg = differing
690 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000691 difflib.ndiff(pprint.pformat(seq1).splitlines(),
692 pprint.pformat(seq2).splitlines()))
Michael Foorda4412872010-06-05 11:46:59 +0000693 standardMsg = self._truncateMessage(standardMsg, diffMsg, max_diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000694 msg = self._formatMessage(msg, standardMsg)
695 self.fail(msg)
696
Michael Foorda4412872010-06-05 11:46:59 +0000697 def _truncateMessage(self, message, diff, max_diff):
698 if max_diff is None or len(diff) <= max_diff:
699 return message + diff
700 return message + diff[:max_diff] + TRUNCATED_DIFF
701
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000702 def assertListEqual(self, list1, list2, msg=None):
703 """A list-specific equality assertion.
704
705 Args:
706 list1: The first list to compare.
707 list2: The second list to compare.
708 msg: Optional message to use on failure instead of a list of
709 differences.
710
711 """
712 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
713
714 def assertTupleEqual(self, tuple1, tuple2, msg=None):
715 """A tuple-specific equality assertion.
716
717 Args:
718 tuple1: The first tuple to compare.
719 tuple2: The second tuple to compare.
720 msg: Optional message to use on failure instead of a list of
721 differences.
722 """
723 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
724
725 def assertSetEqual(self, set1, set2, msg=None):
726 """A set-specific equality assertion.
727
728 Args:
729 set1: The first set to compare.
730 set2: The second set to compare.
731 msg: Optional message to use on failure instead of a list of
732 differences.
733
Michael Foord98e7b762010-03-20 03:00:34 +0000734 assertSetEqual uses ducktyping to support different types of sets, and
735 is optimized for sets specifically (parameters must support a
736 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000737 """
738 try:
739 difference1 = set1.difference(set2)
740 except TypeError, e:
741 self.fail('invalid type when attempting set difference: %s' % e)
742 except AttributeError, e:
743 self.fail('first argument does not support set difference: %s' % e)
744
745 try:
746 difference2 = set2.difference(set1)
747 except TypeError, e:
748 self.fail('invalid type when attempting set difference: %s' % e)
749 except AttributeError, e:
750 self.fail('second argument does not support set difference: %s' % e)
751
752 if not (difference1 or difference2):
753 return
754
755 lines = []
756 if difference1:
757 lines.append('Items in the first set but not the second:')
758 for item in difference1:
759 lines.append(repr(item))
760 if difference2:
761 lines.append('Items in the second set but not the first:')
762 for item in difference2:
763 lines.append(repr(item))
764
765 standardMsg = '\n'.join(lines)
766 self.fail(self._formatMessage(msg, standardMsg))
767
768 def assertIn(self, member, container, msg=None):
769 """Just like self.assertTrue(a in b), but with a nicer default message."""
770 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000771 standardMsg = '%s not found in %s' % (safe_repr(member),
772 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000773 self.fail(self._formatMessage(msg, standardMsg))
774
775 def assertNotIn(self, member, container, msg=None):
776 """Just like self.assertTrue(a not in b), but with a nicer default message."""
777 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000778 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
779 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000780 self.fail(self._formatMessage(msg, standardMsg))
781
782 def assertIs(self, expr1, expr2, msg=None):
783 """Just like self.assertTrue(a is b), but with a nicer default message."""
784 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000785 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000786 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000787 self.fail(self._formatMessage(msg, standardMsg))
788
789 def assertIsNot(self, expr1, expr2, msg=None):
790 """Just like self.assertTrue(a is not b), but with a nicer default message."""
791 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000792 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000793 self.fail(self._formatMessage(msg, standardMsg))
794
795 def assertDictEqual(self, d1, d2, msg=None):
796 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
797 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
798
799 if d1 != d2:
800 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
801 pprint.pformat(d1).splitlines(),
802 pprint.pformat(d2).splitlines())))
803 self.fail(self._formatMessage(msg, standardMsg))
804
805 def assertDictContainsSubset(self, expected, actual, msg=None):
806 """Checks whether actual is a superset of expected."""
807 missing = []
808 mismatched = []
809 for key, value in expected.iteritems():
810 if key not in actual:
811 missing.append(key)
812 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000813 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000814 (safe_repr(key), safe_repr(value),
815 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000816
817 if not (missing or mismatched):
818 return
819
820 standardMsg = ''
821 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000822 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
823 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000824 if mismatched:
825 if standardMsg:
826 standardMsg += '; '
827 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
828
829 self.fail(self._formatMessage(msg, standardMsg))
830
Michael Foord98e7b762010-03-20 03:00:34 +0000831 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
832 """An unordered sequence / set specific comparison. It asserts that
833 expected_seq and actual_seq contain the same elements. It is
834 the equivalent of::
835
836 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000837
838 Raises with an error message listing which elements of expected_seq
839 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000840
Michael Foord98e7b762010-03-20 03:00:34 +0000841 Asserts that each element has the same count in both sequences.
842 Example:
843 - [0, 1, 1] and [1, 0, 1] compare equal.
844 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000845 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000846 with warnings.catch_warnings():
847 if sys.py3kwarning:
848 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000849 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000850 "builtin_function_or_method order comparisons",
851 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000852 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000853 try:
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000854 expected = sorted(expected_seq)
855 actual = sorted(actual_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000856 except TypeError:
857 # Unsortable items (example: set(), complex(), ...)
858 expected = list(expected_seq)
859 actual = list(actual_seq)
860 missing, unexpected = unorderable_list_difference(
861 expected, actual, ignore_duplicate=False
862 )
863 else:
864 return self.assertSequenceEqual(expected, actual, msg=msg)
865
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000866 errors = []
867 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000868 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000869 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000870 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000871 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000872 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000873 if errors:
874 standardMsg = '\n'.join(errors)
875 self.fail(self._formatMessage(msg, standardMsg))
876
877 def assertMultiLineEqual(self, first, second, msg=None):
878 """Assert that two multi-line strings are equal."""
879 self.assert_(isinstance(first, basestring), (
880 'First argument is not a string'))
881 self.assert_(isinstance(second, basestring), (
882 'Second argument is not a string'))
883
884 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000885 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
886 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000887 self.fail(self._formatMessage(msg, standardMsg))
888
889 def assertLess(self, a, b, msg=None):
890 """Just like self.assertTrue(a < b), but with a nicer default message."""
891 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000892 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000893 self.fail(self._formatMessage(msg, standardMsg))
894
895 def assertLessEqual(self, a, b, msg=None):
896 """Just like self.assertTrue(a <= b), but with a nicer default message."""
897 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000898 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000899 self.fail(self._formatMessage(msg, standardMsg))
900
901 def assertGreater(self, a, b, msg=None):
902 """Just like self.assertTrue(a > b), but with a nicer default message."""
903 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000904 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000905 self.fail(self._formatMessage(msg, standardMsg))
906
907 def assertGreaterEqual(self, a, b, msg=None):
908 """Just like self.assertTrue(a >= b), but with a nicer default message."""
909 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000910 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000911 self.fail(self._formatMessage(msg, standardMsg))
912
913 def assertIsNone(self, obj, msg=None):
914 """Same as self.assertTrue(obj is None), with a nicer default message."""
915 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000916 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000917 self.fail(self._formatMessage(msg, standardMsg))
918
919 def assertIsNotNone(self, obj, msg=None):
920 """Included for symmetry with assertIsNone."""
921 if obj is None:
922 standardMsg = 'unexpectedly None'
923 self.fail(self._formatMessage(msg, standardMsg))
924
Georg Brandlf895cf52009-10-01 20:59:31 +0000925 def assertIsInstance(self, obj, cls, msg=None):
926 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
927 default message."""
928 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000929 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000930 self.fail(self._formatMessage(msg, standardMsg))
931
932 def assertNotIsInstance(self, obj, cls, msg=None):
933 """Included for symmetry with assertIsInstance."""
934 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000935 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000936 self.fail(self._formatMessage(msg, standardMsg))
937
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000938 def assertRaisesRegexp(self, expected_exception, expected_regexp,
939 callable_obj=None, *args, **kwargs):
940 """Asserts that the message in a raised exception matches a regexp.
941
942 Args:
943 expected_exception: Exception class expected to be raised.
944 expected_regexp: Regexp (re pattern object or string) expected
945 to be found in error message.
946 callable_obj: Function to be called.
947 args: Extra args.
948 kwargs: Extra kwargs.
949 """
950 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
951 if callable_obj is None:
952 return context
953 with context:
954 callable_obj(*args, **kwargs)
955
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000956 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000957 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000958 if isinstance(expected_regexp, basestring):
959 expected_regexp = re.compile(expected_regexp)
960 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000961 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000962 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000963 raise self.failureException(msg)
964
Michael Foorda04c7a02010-04-02 22:55:59 +0000965 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000966 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +0000967 if isinstance(unexpected_regexp, basestring):
968 unexpected_regexp = re.compile(unexpected_regexp)
969 match = unexpected_regexp.search(text)
970 if match:
971 msg = msg or "Regexp matched"
972 msg = '%s: %r matches %r in %r' % (msg,
973 text[match.start():match.end()],
974 unexpected_regexp.pattern,
975 text)
976 raise self.failureException(msg)
977
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000978
979class FunctionTestCase(TestCase):
980 """A test case that wraps a test function.
981
982 This is useful for slipping pre-existing test functions into the
983 unittest framework. Optionally, set-up and tidy-up functions can be
984 supplied. As with TestCase, the tidy-up ('tearDown') function will
985 always be called if the set-up ('setUp') function ran successfully.
986 """
987
988 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
989 super(FunctionTestCase, self).__init__()
990 self._setUpFunc = setUp
991 self._tearDownFunc = tearDown
992 self._testFunc = testFunc
993 self._description = description
994
995 def setUp(self):
996 if self._setUpFunc is not None:
997 self._setUpFunc()
998
999 def tearDown(self):
1000 if self._tearDownFunc is not None:
1001 self._tearDownFunc()
1002
1003 def runTest(self):
1004 self._testFunc()
1005
1006 def id(self):
1007 return self._testFunc.__name__
1008
1009 def __eq__(self, other):
1010 if not isinstance(other, self.__class__):
1011 return NotImplemented
1012
1013 return self._setUpFunc == other._setUpFunc and \
1014 self._tearDownFunc == other._tearDownFunc and \
1015 self._testFunc == other._testFunc and \
1016 self._description == other._description
1017
1018 def __ne__(self, other):
1019 return not self == other
1020
1021 def __hash__(self):
1022 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1023 self._testFunc, self._description))
1024
1025 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001026 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001027 self._testFunc.__name__)
1028
1029 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001030 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001031 self._testFunc)
1032
1033 def shortDescription(self):
1034 if self._description is not None:
1035 return self._description
1036 doc = self._testFunc.__doc__
1037 return doc and doc.split("\n")[0].strip() or None