blob: cbbe2b5962e4c9cac4853965a97dbc436fba5d70 [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
16
17
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
592 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
593 """An equality assertion for ordered sequences (like lists and tuples).
594
R. David Murray05b41712010-01-29 19:35:39 +0000595 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000596 which can be indexed, has a length, and has an equality operator.
597
598 Args:
599 seq1: The first sequence to compare.
600 seq2: The second sequence to compare.
601 seq_type: The expected datatype of the sequences, or None if no
602 datatype should be enforced.
603 msg: Optional message to use on failure instead of a list of
604 differences.
605 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000606 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000607 seq_type_name = seq_type.__name__
608 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000609 raise self.failureException('First sequence is not a %s: %s'
610 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000611 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000612 raise self.failureException('Second sequence is not a %s: %s'
613 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000614 else:
615 seq_type_name = "sequence"
616
617 differing = None
618 try:
619 len1 = len(seq1)
620 except (TypeError, NotImplementedError):
621 differing = 'First %s has no length. Non-sequence?' % (
622 seq_type_name)
623
624 if differing is None:
625 try:
626 len2 = len(seq2)
627 except (TypeError, NotImplementedError):
628 differing = 'Second %s has no length. Non-sequence?' % (
629 seq_type_name)
630
631 if differing is None:
632 if seq1 == seq2:
633 return
634
Michael Foord225a0992010-02-18 20:30:09 +0000635 seq1_repr = safe_repr(seq1)
636 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000637 if len(seq1_repr) > 30:
638 seq1_repr = seq1_repr[:30] + '...'
639 if len(seq2_repr) > 30:
640 seq2_repr = seq2_repr[:30] + '...'
641 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
642 differing = '%ss differ: %s != %s\n' % elements
643
644 for i in xrange(min(len1, len2)):
645 try:
646 item1 = seq1[i]
647 except (TypeError, IndexError, NotImplementedError):
648 differing += ('\nUnable to index element %d of first %s\n' %
649 (i, seq_type_name))
650 break
651
652 try:
653 item2 = seq2[i]
654 except (TypeError, IndexError, NotImplementedError):
655 differing += ('\nUnable to index element %d of second %s\n' %
656 (i, seq_type_name))
657 break
658
659 if item1 != item2:
660 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
661 (i, item1, item2))
662 break
663 else:
664 if (len1 == len2 and seq_type is None and
665 type(seq1) != type(seq2)):
666 # The sequences are the same, but have differing types.
667 return
668
669 if len1 > len2:
670 differing += ('\nFirst %s contains %d additional '
671 'elements.\n' % (seq_type_name, len1 - len2))
672 try:
673 differing += ('First extra element %d:\n%s\n' %
674 (len2, seq1[len2]))
675 except (TypeError, IndexError, NotImplementedError):
676 differing += ('Unable to index element %d '
677 'of first %s\n' % (len2, seq_type_name))
678 elif len1 < len2:
679 differing += ('\nSecond %s contains %d additional '
680 'elements.\n' % (seq_type_name, len2 - len1))
681 try:
682 differing += ('First extra element %d:\n%s\n' %
683 (len1, seq2[len1]))
684 except (TypeError, IndexError, NotImplementedError):
685 differing += ('Unable to index element %d '
686 'of second %s\n' % (len1, seq_type_name))
Georg Brandl46cc46a2009-10-01 20:11:14 +0000687 standardMsg = differing + '\n' + '\n'.join(
688 difflib.ndiff(pprint.pformat(seq1).splitlines(),
689 pprint.pformat(seq2).splitlines()))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000690 msg = self._formatMessage(msg, standardMsg)
691 self.fail(msg)
692
693 def assertListEqual(self, list1, list2, msg=None):
694 """A list-specific equality assertion.
695
696 Args:
697 list1: The first list to compare.
698 list2: The second list to compare.
699 msg: Optional message to use on failure instead of a list of
700 differences.
701
702 """
703 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
704
705 def assertTupleEqual(self, tuple1, tuple2, msg=None):
706 """A tuple-specific equality assertion.
707
708 Args:
709 tuple1: The first tuple to compare.
710 tuple2: The second tuple to compare.
711 msg: Optional message to use on failure instead of a list of
712 differences.
713 """
714 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
715
716 def assertSetEqual(self, set1, set2, msg=None):
717 """A set-specific equality assertion.
718
719 Args:
720 set1: The first set to compare.
721 set2: The second set to compare.
722 msg: Optional message to use on failure instead of a list of
723 differences.
724
Michael Foord98e7b762010-03-20 03:00:34 +0000725 assertSetEqual uses ducktyping to support different types of sets, and
726 is optimized for sets specifically (parameters must support a
727 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000728 """
729 try:
730 difference1 = set1.difference(set2)
731 except TypeError, e:
732 self.fail('invalid type when attempting set difference: %s' % e)
733 except AttributeError, e:
734 self.fail('first argument does not support set difference: %s' % e)
735
736 try:
737 difference2 = set2.difference(set1)
738 except TypeError, e:
739 self.fail('invalid type when attempting set difference: %s' % e)
740 except AttributeError, e:
741 self.fail('second argument does not support set difference: %s' % e)
742
743 if not (difference1 or difference2):
744 return
745
746 lines = []
747 if difference1:
748 lines.append('Items in the first set but not the second:')
749 for item in difference1:
750 lines.append(repr(item))
751 if difference2:
752 lines.append('Items in the second set but not the first:')
753 for item in difference2:
754 lines.append(repr(item))
755
756 standardMsg = '\n'.join(lines)
757 self.fail(self._formatMessage(msg, standardMsg))
758
759 def assertIn(self, member, container, msg=None):
760 """Just like self.assertTrue(a in b), but with a nicer default message."""
761 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000762 standardMsg = '%s not found in %s' % (safe_repr(member),
763 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000764 self.fail(self._formatMessage(msg, standardMsg))
765
766 def assertNotIn(self, member, container, msg=None):
767 """Just like self.assertTrue(a not in b), but with a nicer default message."""
768 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000769 standardMsg = '%s unexpectedly 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 assertIs(self, expr1, expr2, msg=None):
774 """Just like self.assertTrue(a is b), but with a nicer default message."""
775 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000776 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000777 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000778 self.fail(self._formatMessage(msg, standardMsg))
779
780 def assertIsNot(self, expr1, expr2, msg=None):
781 """Just like self.assertTrue(a is not b), but with a nicer default message."""
782 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000783 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000784 self.fail(self._formatMessage(msg, standardMsg))
785
786 def assertDictEqual(self, d1, d2, msg=None):
787 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
788 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
789
790 if d1 != d2:
791 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
792 pprint.pformat(d1).splitlines(),
793 pprint.pformat(d2).splitlines())))
794 self.fail(self._formatMessage(msg, standardMsg))
795
796 def assertDictContainsSubset(self, expected, actual, msg=None):
797 """Checks whether actual is a superset of expected."""
798 missing = []
799 mismatched = []
800 for key, value in expected.iteritems():
801 if key not in actual:
802 missing.append(key)
803 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000804 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000805 (safe_repr(key), safe_repr(value),
806 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000807
808 if not (missing or mismatched):
809 return
810
811 standardMsg = ''
812 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000813 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
814 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000815 if mismatched:
816 if standardMsg:
817 standardMsg += '; '
818 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
819
820 self.fail(self._formatMessage(msg, standardMsg))
821
Michael Foord98e7b762010-03-20 03:00:34 +0000822 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
823 """An unordered sequence / set specific comparison. It asserts that
824 expected_seq and actual_seq contain the same elements. It is
825 the equivalent of::
826
827 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000828
829 Raises with an error message listing which elements of expected_seq
830 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000831
Michael Foord98e7b762010-03-20 03:00:34 +0000832 Asserts that each element has the same count in both sequences.
833 Example:
834 - [0, 1, 1] and [1, 0, 1] compare equal.
835 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000836 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000837 with warnings.catch_warnings():
838 if sys.py3kwarning:
839 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000840 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000841 "builtin_function_or_method order comparisons",
842 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000843 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000844 try:
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000845 expected = sorted(expected_seq)
846 actual = sorted(actual_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000847 except TypeError:
848 # Unsortable items (example: set(), complex(), ...)
849 expected = list(expected_seq)
850 actual = list(actual_seq)
851 missing, unexpected = unorderable_list_difference(
852 expected, actual, ignore_duplicate=False
853 )
854 else:
855 return self.assertSequenceEqual(expected, actual, msg=msg)
856
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000857 errors = []
858 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000859 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000860 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000861 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000862 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000863 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000864 if errors:
865 standardMsg = '\n'.join(errors)
866 self.fail(self._formatMessage(msg, standardMsg))
867
868 def assertMultiLineEqual(self, first, second, msg=None):
869 """Assert that two multi-line strings are equal."""
870 self.assert_(isinstance(first, basestring), (
871 'First argument is not a string'))
872 self.assert_(isinstance(second, basestring), (
873 'Second argument is not a string'))
874
875 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000876 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
877 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000878 self.fail(self._formatMessage(msg, standardMsg))
879
880 def assertLess(self, a, b, msg=None):
881 """Just like self.assertTrue(a < b), but with a nicer default message."""
882 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000883 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000884 self.fail(self._formatMessage(msg, standardMsg))
885
886 def assertLessEqual(self, a, b, msg=None):
887 """Just like self.assertTrue(a <= b), but with a nicer default message."""
888 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000889 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000890 self.fail(self._formatMessage(msg, standardMsg))
891
892 def assertGreater(self, a, b, msg=None):
893 """Just like self.assertTrue(a > b), but with a nicer default message."""
894 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000895 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000896 self.fail(self._formatMessage(msg, standardMsg))
897
898 def assertGreaterEqual(self, a, b, msg=None):
899 """Just like self.assertTrue(a >= b), but with a nicer default message."""
900 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000901 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000902 self.fail(self._formatMessage(msg, standardMsg))
903
904 def assertIsNone(self, obj, msg=None):
905 """Same as self.assertTrue(obj is None), with a nicer default message."""
906 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000907 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000908 self.fail(self._formatMessage(msg, standardMsg))
909
910 def assertIsNotNone(self, obj, msg=None):
911 """Included for symmetry with assertIsNone."""
912 if obj is None:
913 standardMsg = 'unexpectedly None'
914 self.fail(self._formatMessage(msg, standardMsg))
915
Georg Brandlf895cf52009-10-01 20:59:31 +0000916 def assertIsInstance(self, obj, cls, msg=None):
917 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
918 default message."""
919 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000920 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000921 self.fail(self._formatMessage(msg, standardMsg))
922
923 def assertNotIsInstance(self, obj, cls, msg=None):
924 """Included for symmetry with assertIsInstance."""
925 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000926 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000927 self.fail(self._formatMessage(msg, standardMsg))
928
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000929 def assertRaisesRegexp(self, expected_exception, expected_regexp,
930 callable_obj=None, *args, **kwargs):
931 """Asserts that the message in a raised exception matches a regexp.
932
933 Args:
934 expected_exception: Exception class expected to be raised.
935 expected_regexp: Regexp (re pattern object or string) expected
936 to be found in error message.
937 callable_obj: Function to be called.
938 args: Extra args.
939 kwargs: Extra kwargs.
940 """
941 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
942 if callable_obj is None:
943 return context
944 with context:
945 callable_obj(*args, **kwargs)
946
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000947 def assertRegexpMatches(self, text, expected_regexp, msg=None):
948 if isinstance(expected_regexp, basestring):
949 expected_regexp = re.compile(expected_regexp)
950 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000951 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000952 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000953 raise self.failureException(msg)
954
Michael Foorda04c7a02010-04-02 22:55:59 +0000955 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
956 if isinstance(unexpected_regexp, basestring):
957 unexpected_regexp = re.compile(unexpected_regexp)
958 match = unexpected_regexp.search(text)
959 if match:
960 msg = msg or "Regexp matched"
961 msg = '%s: %r matches %r in %r' % (msg,
962 text[match.start():match.end()],
963 unexpected_regexp.pattern,
964 text)
965 raise self.failureException(msg)
966
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000967
968class FunctionTestCase(TestCase):
969 """A test case that wraps a test function.
970
971 This is useful for slipping pre-existing test functions into the
972 unittest framework. Optionally, set-up and tidy-up functions can be
973 supplied. As with TestCase, the tidy-up ('tearDown') function will
974 always be called if the set-up ('setUp') function ran successfully.
975 """
976
977 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
978 super(FunctionTestCase, self).__init__()
979 self._setUpFunc = setUp
980 self._tearDownFunc = tearDown
981 self._testFunc = testFunc
982 self._description = description
983
984 def setUp(self):
985 if self._setUpFunc is not None:
986 self._setUpFunc()
987
988 def tearDown(self):
989 if self._tearDownFunc is not None:
990 self._tearDownFunc()
991
992 def runTest(self):
993 self._testFunc()
994
995 def id(self):
996 return self._testFunc.__name__
997
998 def __eq__(self, other):
999 if not isinstance(other, self.__class__):
1000 return NotImplemented
1001
1002 return self._setUpFunc == other._setUpFunc and \
1003 self._tearDownFunc == other._tearDownFunc and \
1004 self._testFunc == other._testFunc and \
1005 self._description == other._description
1006
1007 def __ne__(self, other):
1008 return not self == other
1009
1010 def __hash__(self):
1011 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1012 self._testFunc, self._description))
1013
1014 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001015 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001016 self._testFunc.__name__)
1017
1018 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001019 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001020 self._testFunc)
1021
1022 def shortDescription(self):
1023 if self._description is not None:
1024 return self._description
1025 doc = self._testFunc.__doc__
1026 return doc and doc.split("\n")[0].strip() or None