blob: 94956896f3e8e73f3aab15daf6d79cfa77a9f600 [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
493 def assertAlmostEqual(self, first, second, places=7, msg=None):
494 """Fail if the two objects are unequal as determined by their
495 difference rounded to the given number of decimal places
496 (default 7) and comparing to zero.
497
498 Note that decimal places (from zero) are usually not the same
499 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000500
501 If the two objects compare equal then they will automatically
502 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000503 """
Michael Foordc3f79372009-09-13 16:40:02 +0000504 if first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000505 # shortcut for inf
Michael Foordc3f79372009-09-13 16:40:02 +0000506 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000507 if round(abs(second-first), places) != 0:
Michael Foord225a0992010-02-18 20:30:09 +0000508 standardMsg = '%s != %s within %r places' % (safe_repr(first),
509 safe_repr(second),
510 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000511 msg = self._formatMessage(msg, standardMsg)
512 raise self.failureException(msg)
513
514 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
515 """Fail if the two objects are equal as determined by their
516 difference rounded to the given number of decimal places
517 (default 7) and comparing to zero.
518
519 Note that decimal places (from zero) are usually not the same
520 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000521
522 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000523 """
Michael Foordc3f79372009-09-13 16:40:02 +0000524 if (first == second) or round(abs(second-first), places) == 0:
Michael Foord225a0992010-02-18 20:30:09 +0000525 standardMsg = '%s == %s within %r places' % (safe_repr(first),
526 safe_repr(second),
527 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000528 msg = self._formatMessage(msg, standardMsg)
529 raise self.failureException(msg)
530
531 # Synonyms for assertion methods
532
533 # The plurals are undocumented. Keep them that way to discourage use.
534 # Do not add more. Do not remove.
535 # Going through a deprecation cycle on these would annoy many people.
536 assertEquals = assertEqual
537 assertNotEquals = assertNotEqual
538 assertAlmostEquals = assertAlmostEqual
539 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000540 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000541
542 # These fail* assertion method names are pending deprecation and will
543 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
544 def _deprecate(original_func):
545 def deprecated_func(*args, **kwargs):
546 warnings.warn(
547 'Please use {0} instead.'.format(original_func.__name__),
548 PendingDeprecationWarning, 2)
549 return original_func(*args, **kwargs)
550 return deprecated_func
551
552 failUnlessEqual = _deprecate(assertEqual)
553 failIfEqual = _deprecate(assertNotEqual)
554 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
555 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
556 failUnless = _deprecate(assertTrue)
557 failUnlessRaises = _deprecate(assertRaises)
558 failIf = _deprecate(assertFalse)
559
560 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
561 """An equality assertion for ordered sequences (like lists and tuples).
562
R. David Murray05b41712010-01-29 19:35:39 +0000563 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000564 which can be indexed, has a length, and has an equality operator.
565
566 Args:
567 seq1: The first sequence to compare.
568 seq2: The second sequence to compare.
569 seq_type: The expected datatype of the sequences, or None if no
570 datatype should be enforced.
571 msg: Optional message to use on failure instead of a list of
572 differences.
573 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000574 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000575 seq_type_name = seq_type.__name__
576 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000577 raise self.failureException('First sequence is not a %s: %s'
578 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000579 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000580 raise self.failureException('Second sequence is not a %s: %s'
581 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000582 else:
583 seq_type_name = "sequence"
584
585 differing = None
586 try:
587 len1 = len(seq1)
588 except (TypeError, NotImplementedError):
589 differing = 'First %s has no length. Non-sequence?' % (
590 seq_type_name)
591
592 if differing is None:
593 try:
594 len2 = len(seq2)
595 except (TypeError, NotImplementedError):
596 differing = 'Second %s has no length. Non-sequence?' % (
597 seq_type_name)
598
599 if differing is None:
600 if seq1 == seq2:
601 return
602
Michael Foord225a0992010-02-18 20:30:09 +0000603 seq1_repr = safe_repr(seq1)
604 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000605 if len(seq1_repr) > 30:
606 seq1_repr = seq1_repr[:30] + '...'
607 if len(seq2_repr) > 30:
608 seq2_repr = seq2_repr[:30] + '...'
609 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
610 differing = '%ss differ: %s != %s\n' % elements
611
612 for i in xrange(min(len1, len2)):
613 try:
614 item1 = seq1[i]
615 except (TypeError, IndexError, NotImplementedError):
616 differing += ('\nUnable to index element %d of first %s\n' %
617 (i, seq_type_name))
618 break
619
620 try:
621 item2 = seq2[i]
622 except (TypeError, IndexError, NotImplementedError):
623 differing += ('\nUnable to index element %d of second %s\n' %
624 (i, seq_type_name))
625 break
626
627 if item1 != item2:
628 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
629 (i, item1, item2))
630 break
631 else:
632 if (len1 == len2 and seq_type is None and
633 type(seq1) != type(seq2)):
634 # The sequences are the same, but have differing types.
635 return
636
637 if len1 > len2:
638 differing += ('\nFirst %s contains %d additional '
639 'elements.\n' % (seq_type_name, len1 - len2))
640 try:
641 differing += ('First extra element %d:\n%s\n' %
642 (len2, seq1[len2]))
643 except (TypeError, IndexError, NotImplementedError):
644 differing += ('Unable to index element %d '
645 'of first %s\n' % (len2, seq_type_name))
646 elif len1 < len2:
647 differing += ('\nSecond %s contains %d additional '
648 'elements.\n' % (seq_type_name, len2 - len1))
649 try:
650 differing += ('First extra element %d:\n%s\n' %
651 (len1, seq2[len1]))
652 except (TypeError, IndexError, NotImplementedError):
653 differing += ('Unable to index element %d '
654 'of second %s\n' % (len1, seq_type_name))
Georg Brandl46cc46a2009-10-01 20:11:14 +0000655 standardMsg = differing + '\n' + '\n'.join(
656 difflib.ndiff(pprint.pformat(seq1).splitlines(),
657 pprint.pformat(seq2).splitlines()))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000658 msg = self._formatMessage(msg, standardMsg)
659 self.fail(msg)
660
661 def assertListEqual(self, list1, list2, msg=None):
662 """A list-specific equality assertion.
663
664 Args:
665 list1: The first list to compare.
666 list2: The second list to compare.
667 msg: Optional message to use on failure instead of a list of
668 differences.
669
670 """
671 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
672
673 def assertTupleEqual(self, tuple1, tuple2, msg=None):
674 """A tuple-specific equality assertion.
675
676 Args:
677 tuple1: The first tuple to compare.
678 tuple2: The second tuple to compare.
679 msg: Optional message to use on failure instead of a list of
680 differences.
681 """
682 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
683
684 def assertSetEqual(self, set1, set2, msg=None):
685 """A set-specific equality assertion.
686
687 Args:
688 set1: The first set to compare.
689 set2: The second set to compare.
690 msg: Optional message to use on failure instead of a list of
691 differences.
692
Michael Foord98e7b762010-03-20 03:00:34 +0000693 assertSetEqual uses ducktyping to support different types of sets, and
694 is optimized for sets specifically (parameters must support a
695 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000696 """
697 try:
698 difference1 = set1.difference(set2)
699 except TypeError, e:
700 self.fail('invalid type when attempting set difference: %s' % e)
701 except AttributeError, e:
702 self.fail('first argument does not support set difference: %s' % e)
703
704 try:
705 difference2 = set2.difference(set1)
706 except TypeError, e:
707 self.fail('invalid type when attempting set difference: %s' % e)
708 except AttributeError, e:
709 self.fail('second argument does not support set difference: %s' % e)
710
711 if not (difference1 or difference2):
712 return
713
714 lines = []
715 if difference1:
716 lines.append('Items in the first set but not the second:')
717 for item in difference1:
718 lines.append(repr(item))
719 if difference2:
720 lines.append('Items in the second set but not the first:')
721 for item in difference2:
722 lines.append(repr(item))
723
724 standardMsg = '\n'.join(lines)
725 self.fail(self._formatMessage(msg, standardMsg))
726
727 def assertIn(self, member, container, msg=None):
728 """Just like self.assertTrue(a in b), but with a nicer default message."""
729 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000730 standardMsg = '%s not found in %s' % (safe_repr(member),
731 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000732 self.fail(self._formatMessage(msg, standardMsg))
733
734 def assertNotIn(self, member, container, msg=None):
735 """Just like self.assertTrue(a not in b), but with a nicer default message."""
736 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000737 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
738 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000739 self.fail(self._formatMessage(msg, standardMsg))
740
741 def assertIs(self, expr1, expr2, msg=None):
742 """Just like self.assertTrue(a is b), but with a nicer default message."""
743 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000744 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000745 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000746 self.fail(self._formatMessage(msg, standardMsg))
747
748 def assertIsNot(self, expr1, expr2, msg=None):
749 """Just like self.assertTrue(a is not b), but with a nicer default message."""
750 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000751 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000752 self.fail(self._formatMessage(msg, standardMsg))
753
754 def assertDictEqual(self, d1, d2, msg=None):
755 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
756 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
757
758 if d1 != d2:
759 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
760 pprint.pformat(d1).splitlines(),
761 pprint.pformat(d2).splitlines())))
762 self.fail(self._formatMessage(msg, standardMsg))
763
764 def assertDictContainsSubset(self, expected, actual, msg=None):
765 """Checks whether actual is a superset of expected."""
766 missing = []
767 mismatched = []
768 for key, value in expected.iteritems():
769 if key not in actual:
770 missing.append(key)
771 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000772 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000773 (safe_repr(key), safe_repr(value),
774 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000775
776 if not (missing or mismatched):
777 return
778
779 standardMsg = ''
780 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000781 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
782 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000783 if mismatched:
784 if standardMsg:
785 standardMsg += '; '
786 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
787
788 self.fail(self._formatMessage(msg, standardMsg))
789
Michael Foord98e7b762010-03-20 03:00:34 +0000790 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
791 """An unordered sequence / set specific comparison. It asserts that
792 expected_seq and actual_seq contain the same elements. It is
793 the equivalent of::
794
795 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000796
797 Raises with an error message listing which elements of expected_seq
798 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000799
Michael Foord98e7b762010-03-20 03:00:34 +0000800 Asserts that each element has the same count in both sequences.
801 Example:
802 - [0, 1, 1] and [1, 0, 1] compare equal.
803 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000804 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000805 with warnings.catch_warnings():
806 if sys.py3kwarning:
807 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000808 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000809 "builtin_function_or_method order comparisons",
810 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000811 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000812 try:
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000813 expected = sorted(expected_seq)
814 actual = sorted(actual_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000815 except TypeError:
816 # Unsortable items (example: set(), complex(), ...)
817 expected = list(expected_seq)
818 actual = list(actual_seq)
819 missing, unexpected = unorderable_list_difference(
820 expected, actual, ignore_duplicate=False
821 )
822 else:
823 return self.assertSequenceEqual(expected, actual, msg=msg)
824
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000825 errors = []
826 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000827 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000828 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000829 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000830 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000831 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000832 if errors:
833 standardMsg = '\n'.join(errors)
834 self.fail(self._formatMessage(msg, standardMsg))
835
836 def assertMultiLineEqual(self, first, second, msg=None):
837 """Assert that two multi-line strings are equal."""
838 self.assert_(isinstance(first, basestring), (
839 'First argument is not a string'))
840 self.assert_(isinstance(second, basestring), (
841 'Second argument is not a string'))
842
843 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000844 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
845 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000846 self.fail(self._formatMessage(msg, standardMsg))
847
848 def assertLess(self, a, b, msg=None):
849 """Just like self.assertTrue(a < b), but with a nicer default message."""
850 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000851 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000852 self.fail(self._formatMessage(msg, standardMsg))
853
854 def assertLessEqual(self, a, b, msg=None):
855 """Just like self.assertTrue(a <= b), but with a nicer default message."""
856 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000857 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000858 self.fail(self._formatMessage(msg, standardMsg))
859
860 def assertGreater(self, a, b, msg=None):
861 """Just like self.assertTrue(a > b), but with a nicer default message."""
862 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000863 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000864 self.fail(self._formatMessage(msg, standardMsg))
865
866 def assertGreaterEqual(self, a, b, msg=None):
867 """Just like self.assertTrue(a >= b), but with a nicer default message."""
868 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000869 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000870 self.fail(self._formatMessage(msg, standardMsg))
871
872 def assertIsNone(self, obj, msg=None):
873 """Same as self.assertTrue(obj is None), with a nicer default message."""
874 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000875 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000876 self.fail(self._formatMessage(msg, standardMsg))
877
878 def assertIsNotNone(self, obj, msg=None):
879 """Included for symmetry with assertIsNone."""
880 if obj is None:
881 standardMsg = 'unexpectedly None'
882 self.fail(self._formatMessage(msg, standardMsg))
883
Georg Brandlf895cf52009-10-01 20:59:31 +0000884 def assertIsInstance(self, obj, cls, msg=None):
885 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
886 default message."""
887 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000888 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000889 self.fail(self._formatMessage(msg, standardMsg))
890
891 def assertNotIsInstance(self, obj, cls, msg=None):
892 """Included for symmetry with assertIsInstance."""
893 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000894 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000895 self.fail(self._formatMessage(msg, standardMsg))
896
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000897 def assertRaisesRegexp(self, expected_exception, expected_regexp,
898 callable_obj=None, *args, **kwargs):
899 """Asserts that the message in a raised exception matches a regexp.
900
901 Args:
902 expected_exception: Exception class expected to be raised.
903 expected_regexp: Regexp (re pattern object or string) expected
904 to be found in error message.
905 callable_obj: Function to be called.
906 args: Extra args.
907 kwargs: Extra kwargs.
908 """
909 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
910 if callable_obj is None:
911 return context
912 with context:
913 callable_obj(*args, **kwargs)
914
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000915 def assertRegexpMatches(self, text, expected_regexp, msg=None):
916 if isinstance(expected_regexp, basestring):
917 expected_regexp = re.compile(expected_regexp)
918 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000919 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000920 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000921 raise self.failureException(msg)
922
923
924class FunctionTestCase(TestCase):
925 """A test case that wraps a test function.
926
927 This is useful for slipping pre-existing test functions into the
928 unittest framework. Optionally, set-up and tidy-up functions can be
929 supplied. As with TestCase, the tidy-up ('tearDown') function will
930 always be called if the set-up ('setUp') function ran successfully.
931 """
932
933 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
934 super(FunctionTestCase, self).__init__()
935 self._setUpFunc = setUp
936 self._tearDownFunc = tearDown
937 self._testFunc = testFunc
938 self._description = description
939
940 def setUp(self):
941 if self._setUpFunc is not None:
942 self._setUpFunc()
943
944 def tearDown(self):
945 if self._tearDownFunc is not None:
946 self._tearDownFunc()
947
948 def runTest(self):
949 self._testFunc()
950
951 def id(self):
952 return self._testFunc.__name__
953
954 def __eq__(self, other):
955 if not isinstance(other, self.__class__):
956 return NotImplemented
957
958 return self._setUpFunc == other._setUpFunc and \
959 self._tearDownFunc == other._tearDownFunc and \
960 self._testFunc == other._testFunc and \
961 self._description == other._description
962
963 def __ne__(self, other):
964 return not self == other
965
966 def __hash__(self):
967 return hash((type(self), self._setUpFunc, self._tearDownFunc,
968 self._testFunc, self._description))
969
970 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000971 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000972 self._testFunc.__name__)
973
974 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000975 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000976 self._testFunc)
977
978 def shortDescription(self):
979 if self._description is not None:
980 return self._description
981 doc = self._testFunc.__doc__
982 return doc and doc.split("\n")[0].strip() or None