blob: 7608e301394c81bb96d267b487954ef95cdcd11d [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 Foord01007022010-06-05 11:23:51 +0000693 if max_diff is None or len(diffMsg) <= max_diff:
694 standardMsg += diffMsg
695 else:
696 standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000697 msg = self._formatMessage(msg, standardMsg)
698 self.fail(msg)
699
700 def assertListEqual(self, list1, list2, msg=None):
701 """A list-specific equality assertion.
702
703 Args:
704 list1: The first list to compare.
705 list2: The second list to compare.
706 msg: Optional message to use on failure instead of a list of
707 differences.
708
709 """
710 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
711
712 def assertTupleEqual(self, tuple1, tuple2, msg=None):
713 """A tuple-specific equality assertion.
714
715 Args:
716 tuple1: The first tuple to compare.
717 tuple2: The second tuple to compare.
718 msg: Optional message to use on failure instead of a list of
719 differences.
720 """
721 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
722
723 def assertSetEqual(self, set1, set2, msg=None):
724 """A set-specific equality assertion.
725
726 Args:
727 set1: The first set to compare.
728 set2: The second set to compare.
729 msg: Optional message to use on failure instead of a list of
730 differences.
731
Michael Foord98e7b762010-03-20 03:00:34 +0000732 assertSetEqual uses ducktyping to support different types of sets, and
733 is optimized for sets specifically (parameters must support a
734 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000735 """
736 try:
737 difference1 = set1.difference(set2)
738 except TypeError, e:
739 self.fail('invalid type when attempting set difference: %s' % e)
740 except AttributeError, e:
741 self.fail('first argument does not support set difference: %s' % e)
742
743 try:
744 difference2 = set2.difference(set1)
745 except TypeError, e:
746 self.fail('invalid type when attempting set difference: %s' % e)
747 except AttributeError, e:
748 self.fail('second argument does not support set difference: %s' % e)
749
750 if not (difference1 or difference2):
751 return
752
753 lines = []
754 if difference1:
755 lines.append('Items in the first set but not the second:')
756 for item in difference1:
757 lines.append(repr(item))
758 if difference2:
759 lines.append('Items in the second set but not the first:')
760 for item in difference2:
761 lines.append(repr(item))
762
763 standardMsg = '\n'.join(lines)
764 self.fail(self._formatMessage(msg, standardMsg))
765
766 def assertIn(self, member, container, msg=None):
767 """Just like self.assertTrue(a in b), but with a nicer default message."""
768 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000769 standardMsg = '%s not found in %s' % (safe_repr(member),
770 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000771 self.fail(self._formatMessage(msg, standardMsg))
772
773 def assertNotIn(self, member, container, msg=None):
774 """Just like self.assertTrue(a not in b), but with a nicer default message."""
775 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000776 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
777 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000778 self.fail(self._formatMessage(msg, standardMsg))
779
780 def assertIs(self, expr1, expr2, msg=None):
781 """Just like self.assertTrue(a is b), but with a nicer default message."""
782 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000783 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000784 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000785 self.fail(self._formatMessage(msg, standardMsg))
786
787 def assertIsNot(self, expr1, expr2, msg=None):
788 """Just like self.assertTrue(a is not b), but with a nicer default message."""
789 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000790 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000791 self.fail(self._formatMessage(msg, standardMsg))
792
793 def assertDictEqual(self, d1, d2, msg=None):
794 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
795 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
796
797 if d1 != d2:
798 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
799 pprint.pformat(d1).splitlines(),
800 pprint.pformat(d2).splitlines())))
801 self.fail(self._formatMessage(msg, standardMsg))
802
803 def assertDictContainsSubset(self, expected, actual, msg=None):
804 """Checks whether actual is a superset of expected."""
805 missing = []
806 mismatched = []
807 for key, value in expected.iteritems():
808 if key not in actual:
809 missing.append(key)
810 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000811 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000812 (safe_repr(key), safe_repr(value),
813 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000814
815 if not (missing or mismatched):
816 return
817
818 standardMsg = ''
819 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000820 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
821 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000822 if mismatched:
823 if standardMsg:
824 standardMsg += '; '
825 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
826
827 self.fail(self._formatMessage(msg, standardMsg))
828
Michael Foord98e7b762010-03-20 03:00:34 +0000829 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
830 """An unordered sequence / set specific comparison. It asserts that
831 expected_seq and actual_seq contain the same elements. It is
832 the equivalent of::
833
834 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000835
836 Raises with an error message listing which elements of expected_seq
837 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000838
Michael Foord98e7b762010-03-20 03:00:34 +0000839 Asserts that each element has the same count in both sequences.
840 Example:
841 - [0, 1, 1] and [1, 0, 1] compare equal.
842 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000843 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000844 with warnings.catch_warnings():
845 if sys.py3kwarning:
846 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000847 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000848 "builtin_function_or_method order comparisons",
849 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000850 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000851 try:
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000852 expected = sorted(expected_seq)
853 actual = sorted(actual_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000854 except TypeError:
855 # Unsortable items (example: set(), complex(), ...)
856 expected = list(expected_seq)
857 actual = list(actual_seq)
858 missing, unexpected = unorderable_list_difference(
859 expected, actual, ignore_duplicate=False
860 )
861 else:
862 return self.assertSequenceEqual(expected, actual, msg=msg)
863
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000864 errors = []
865 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000866 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000867 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000868 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000869 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000870 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000871 if errors:
872 standardMsg = '\n'.join(errors)
873 self.fail(self._formatMessage(msg, standardMsg))
874
875 def assertMultiLineEqual(self, first, second, msg=None):
876 """Assert that two multi-line strings are equal."""
877 self.assert_(isinstance(first, basestring), (
878 'First argument is not a string'))
879 self.assert_(isinstance(second, basestring), (
880 'Second argument is not a string'))
881
882 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000883 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
884 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000885 self.fail(self._formatMessage(msg, standardMsg))
886
887 def assertLess(self, a, b, msg=None):
888 """Just like self.assertTrue(a < b), but with a nicer default message."""
889 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000890 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000891 self.fail(self._formatMessage(msg, standardMsg))
892
893 def assertLessEqual(self, a, b, msg=None):
894 """Just like self.assertTrue(a <= b), but with a nicer default message."""
895 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000896 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000897 self.fail(self._formatMessage(msg, standardMsg))
898
899 def assertGreater(self, a, b, msg=None):
900 """Just like self.assertTrue(a > b), but with a nicer default message."""
901 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000902 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000903 self.fail(self._formatMessage(msg, standardMsg))
904
905 def assertGreaterEqual(self, a, b, msg=None):
906 """Just like self.assertTrue(a >= b), but with a nicer default message."""
907 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000908 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000909 self.fail(self._formatMessage(msg, standardMsg))
910
911 def assertIsNone(self, obj, msg=None):
912 """Same as self.assertTrue(obj is None), with a nicer default message."""
913 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000914 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000915 self.fail(self._formatMessage(msg, standardMsg))
916
917 def assertIsNotNone(self, obj, msg=None):
918 """Included for symmetry with assertIsNone."""
919 if obj is None:
920 standardMsg = 'unexpectedly None'
921 self.fail(self._formatMessage(msg, standardMsg))
922
Georg Brandlf895cf52009-10-01 20:59:31 +0000923 def assertIsInstance(self, obj, cls, msg=None):
924 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
925 default message."""
926 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000927 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000928 self.fail(self._formatMessage(msg, standardMsg))
929
930 def assertNotIsInstance(self, obj, cls, msg=None):
931 """Included for symmetry with assertIsInstance."""
932 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000933 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000934 self.fail(self._formatMessage(msg, standardMsg))
935
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000936 def assertRaisesRegexp(self, expected_exception, expected_regexp,
937 callable_obj=None, *args, **kwargs):
938 """Asserts that the message in a raised exception matches a regexp.
939
940 Args:
941 expected_exception: Exception class expected to be raised.
942 expected_regexp: Regexp (re pattern object or string) expected
943 to be found in error message.
944 callable_obj: Function to be called.
945 args: Extra args.
946 kwargs: Extra kwargs.
947 """
948 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
949 if callable_obj is None:
950 return context
951 with context:
952 callable_obj(*args, **kwargs)
953
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000954 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000955 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000956 if isinstance(expected_regexp, basestring):
957 expected_regexp = re.compile(expected_regexp)
958 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000959 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000960 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000961 raise self.failureException(msg)
962
Michael Foorda04c7a02010-04-02 22:55:59 +0000963 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000964 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +0000965 if isinstance(unexpected_regexp, basestring):
966 unexpected_regexp = re.compile(unexpected_regexp)
967 match = unexpected_regexp.search(text)
968 if match:
969 msg = msg or "Regexp matched"
970 msg = '%s: %r matches %r in %r' % (msg,
971 text[match.start():match.end()],
972 unexpected_regexp.pattern,
973 text)
974 raise self.failureException(msg)
975
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000976
977class FunctionTestCase(TestCase):
978 """A test case that wraps a test function.
979
980 This is useful for slipping pre-existing test functions into the
981 unittest framework. Optionally, set-up and tidy-up functions can be
982 supplied. As with TestCase, the tidy-up ('tearDown') function will
983 always be called if the set-up ('setUp') function ran successfully.
984 """
985
986 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
987 super(FunctionTestCase, self).__init__()
988 self._setUpFunc = setUp
989 self._tearDownFunc = tearDown
990 self._testFunc = testFunc
991 self._description = description
992
993 def setUp(self):
994 if self._setUpFunc is not None:
995 self._setUpFunc()
996
997 def tearDown(self):
998 if self._tearDownFunc is not None:
999 self._tearDownFunc()
1000
1001 def runTest(self):
1002 self._testFunc()
1003
1004 def id(self):
1005 return self._testFunc.__name__
1006
1007 def __eq__(self, other):
1008 if not isinstance(other, self.__class__):
1009 return NotImplemented
1010
1011 return self._setUpFunc == other._setUpFunc and \
1012 self._tearDownFunc == other._tearDownFunc and \
1013 self._testFunc == other._testFunc and \
1014 self._description == other._description
1015
1016 def __ne__(self, other):
1017 return not self == other
1018
1019 def __hash__(self):
1020 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1021 self._testFunc, self._description))
1022
1023 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001024 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001025 self._testFunc.__name__)
1026
1027 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001028 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001029 self._testFunc)
1030
1031 def shortDescription(self):
1032 if self._description is not None:
1033 return self._description
1034 doc = self._testFunc.__doc__
1035 return doc and doc.split("\n")[0].strip() or None