blob: feae3fa7a67976e843619f5f4a91376e094de9c3 [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
15class SkipTest(Exception):
16 """
17 Raise this exception in a test to skip it.
18
19 Usually you can use TestResult.skip() or one of the skipping decorators
20 instead of raising this directly.
21 """
22 pass
23
24class _ExpectedFailure(Exception):
25 """
26 Raise this when a test is expected to fail.
27
28 This is an implementation detail.
29 """
30
31 def __init__(self, exc_info):
32 super(_ExpectedFailure, self).__init__()
33 self.exc_info = exc_info
34
35class _UnexpectedSuccess(Exception):
36 """
37 The test was supposed to fail, but it didn't!
38 """
39 pass
40
41def _id(obj):
42 return obj
43
44def skip(reason):
45 """
46 Unconditionally skip a test.
47 """
48 def decorator(test_item):
Michael Foord53e8eea2010-03-07 20:22:12 +000049 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
50 @functools.wraps(test_item)
51 def skip_wrapper(*args, **kwargs):
52 raise SkipTest(reason)
53 test_item = skip_wrapper
54
55 test_item.__unittest_skip__ = True
56 test_item.__unittest_skip_why__ = reason
57 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000058 return decorator
59
60def skipIf(condition, reason):
61 """
62 Skip a test if the condition is true.
63 """
64 if condition:
65 return skip(reason)
66 return _id
67
68def skipUnless(condition, reason):
69 """
70 Skip a test unless the condition is true.
71 """
72 if not condition:
73 return skip(reason)
74 return _id
75
76
77def expectedFailure(func):
78 @functools.wraps(func)
79 def wrapper(*args, **kwargs):
80 try:
81 func(*args, **kwargs)
82 except Exception:
83 raise _ExpectedFailure(sys.exc_info())
84 raise _UnexpectedSuccess
85 return wrapper
86
87
88class _AssertRaisesContext(object):
89 """A context manager used to implement TestCase.assertRaises* methods."""
90
91 def __init__(self, expected, test_case, expected_regexp=None):
92 self.expected = expected
93 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +000094 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000095
96 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +000097 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000098
99 def __exit__(self, exc_type, exc_value, tb):
100 if exc_type is None:
101 try:
102 exc_name = self.expected.__name__
103 except AttributeError:
104 exc_name = str(self.expected)
105 raise self.failureException(
106 "{0} not raised".format(exc_name))
107 if not issubclass(exc_type, self.expected):
108 # let unexpected exceptions pass through
109 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000110 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000111 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000112 return True
113
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000114 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000115 if isinstance(expected_regexp, basestring):
116 expected_regexp = re.compile(expected_regexp)
117 if not expected_regexp.search(str(exc_value)):
118 raise self.failureException('"%s" does not match "%s"' %
119 (expected_regexp.pattern, str(exc_value)))
120 return True
121
122
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000123class TestCase(object):
124 """A class whose instances are single test cases.
125
126 By default, the test code itself should be placed in a method named
127 'runTest'.
128
129 If the fixture may be used for many test cases, create as
130 many test methods as are needed. When instantiating such a TestCase
131 subclass, specify in the constructor arguments the name of the test method
132 that the instance is to execute.
133
134 Test authors should subclass TestCase for their own tests. Construction
135 and deconstruction of the test's environment ('fixture') can be
136 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
137
138 If it is necessary to override the __init__ method, the base class
139 __init__ method must always be called. It is important that subclasses
140 should not change the signature of their __init__ method, since instances
141 of the classes are instantiated automatically by parts of the framework
142 in order to be run.
143 """
144
145 # This attribute determines which exception will be raised when
146 # the instance's assertion methods fail; test methods raising this
147 # exception will be deemed to have 'failed' rather than 'errored'
148
149 failureException = AssertionError
150
151 # This attribute determines whether long messages (including repr of
152 # objects used in assert methods) will be printed on failure in *addition*
153 # to any explicit message passed.
154
155 longMessage = False
156
Michael Foord5ffa3252010-03-07 22:04:55 +0000157 # Attribute used by TestSuite for classSetUp
158
159 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000160
161 def __init__(self, methodName='runTest'):
162 """Create an instance of the class that will use the named test
163 method when executed. Raises a ValueError if the instance does
164 not have a method with the specified name.
165 """
166 self._testMethodName = methodName
167 self._resultForDoCleanups = None
168 try:
169 testMethod = getattr(self, methodName)
170 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000171 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000172 (self.__class__, methodName))
173 self._testMethodDoc = testMethod.__doc__
174 self._cleanups = []
175
176 # Map types to custom assertEqual functions that will compare
177 # instances of said type in more detail to generate a more useful
178 # error message.
179 self._type_equality_funcs = {}
180 self.addTypeEqualityFunc(dict, self.assertDictEqual)
181 self.addTypeEqualityFunc(list, self.assertListEqual)
182 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
183 self.addTypeEqualityFunc(set, self.assertSetEqual)
184 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foordfe6349c2010-02-08 22:41:16 +0000185 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000186
187 def addTypeEqualityFunc(self, typeobj, function):
188 """Add a type specific assertEqual style function to compare a type.
189
190 This method is for use by TestCase subclasses that need to register
191 their own type equality functions to provide nicer error messages.
192
193 Args:
194 typeobj: The data type to call this function on when both values
195 are of the same type in assertEqual().
196 function: The callable taking two arguments and an optional
197 msg= argument that raises self.failureException with a
198 useful error message when the two arguments are not equal.
199 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000200 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000201
202 def addCleanup(self, function, *args, **kwargs):
203 """Add a function, with arguments, to be called when the test is
204 completed. Functions added are called on a LIFO basis and are
205 called after tearDown on test failure or success.
206
207 Cleanup items are called even if setUp fails (unlike tearDown)."""
208 self._cleanups.append((function, args, kwargs))
209
210 def setUp(self):
211 "Hook method for setting up the test fixture before exercising it."
212 pass
213
214 def tearDown(self):
215 "Hook method for deconstructing the test fixture after testing it."
216 pass
217
Michael Foord5ffa3252010-03-07 22:04:55 +0000218 @classmethod
219 def setUpClass(cls):
220 "Hook method for setting up class fixture before running tests in the class."
221
222 @classmethod
223 def tearDownClass(cls):
224 "Hook method for deconstructing the class fixture after running all tests in the class."
225
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000226 def countTestCases(self):
227 return 1
228
229 def defaultTestResult(self):
230 return result.TestResult()
231
232 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000233 """Returns a one-line description of the test, or None if no
234 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000235
Michael Foorddb43b5a2010-02-10 14:25:12 +0000236 The default implementation of this method returns the first line of
237 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000238 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000239 doc = self._testMethodDoc
240 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000241
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000242
243 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000244 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000245
246 def __eq__(self, other):
247 if type(self) is not type(other):
248 return NotImplemented
249
250 return self._testMethodName == other._testMethodName
251
252 def __ne__(self, other):
253 return not self == other
254
255 def __hash__(self):
256 return hash((type(self), self._testMethodName))
257
258 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000259 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000260
261 def __repr__(self):
262 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000263 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000264
Michael Foordae3db0a2010-02-22 23:28:32 +0000265 def _addSkip(self, result, reason):
266 addSkip = getattr(result, 'addSkip', None)
267 if addSkip is not None:
268 addSkip(self, reason)
269 else:
270 warnings.warn("TestResult has no addSkip method, skips not reported",
271 RuntimeWarning, 2)
272 result.addSuccess(self)
273
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000274 def run(self, result=None):
275 orig_result = result
276 if result is None:
277 result = self.defaultTestResult()
278 startTestRun = getattr(result, 'startTestRun', None)
279 if startTestRun is not None:
280 startTestRun()
281
282 self._resultForDoCleanups = result
283 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000284
285 testMethod = getattr(self, self._testMethodName)
286 if (getattr(self.__class__, "__unittest_skip__", False) or
287 getattr(testMethod, "__unittest_skip__", False)):
288 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000289 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000290 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
291 or getattr(testMethod, '__unittest_skip_why__', ''))
292 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000293 finally:
294 result.stopTest(self)
295 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000296 try:
297 success = False
298 try:
299 self.setUp()
300 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000301 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000302 except Exception:
303 result.addError(self, sys.exc_info())
304 else:
305 try:
306 testMethod()
307 except self.failureException:
308 result.addFailure(self, sys.exc_info())
309 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000310 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
311 if addExpectedFailure is not None:
312 addExpectedFailure(self, e.exc_info)
313 else:
314 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
315 RuntimeWarning)
316 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000317 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000318 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
319 if addUnexpectedSuccess is not None:
320 addUnexpectedSuccess(self)
321 else:
322 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
323 RuntimeWarning)
324 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000325 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000326 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000327 except Exception:
328 result.addError(self, sys.exc_info())
329 else:
330 success = True
331
332 try:
333 self.tearDown()
334 except Exception:
335 result.addError(self, sys.exc_info())
336 success = False
337
338 cleanUpSuccess = self.doCleanups()
339 success = success and cleanUpSuccess
340 if success:
341 result.addSuccess(self)
342 finally:
343 result.stopTest(self)
344 if orig_result is None:
345 stopTestRun = getattr(result, 'stopTestRun', None)
346 if stopTestRun is not None:
347 stopTestRun()
348
349 def doCleanups(self):
350 """Execute all cleanup functions. Normally called for you after
351 tearDown."""
352 result = self._resultForDoCleanups
353 ok = True
354 while self._cleanups:
355 function, args, kwargs = self._cleanups.pop(-1)
356 try:
357 function(*args, **kwargs)
358 except Exception:
359 ok = False
360 result.addError(self, sys.exc_info())
361 return ok
362
363 def __call__(self, *args, **kwds):
364 return self.run(*args, **kwds)
365
366 def debug(self):
367 """Run the test without collecting errors in a TestResult"""
368 self.setUp()
369 getattr(self, self._testMethodName)()
370 self.tearDown()
371
372 def skipTest(self, reason):
373 """Skip this test."""
374 raise SkipTest(reason)
375
376 def fail(self, msg=None):
377 """Fail immediately, with the given message."""
378 raise self.failureException(msg)
379
380 def assertFalse(self, expr, msg=None):
381 "Fail the test if the expression is true."
382 if expr:
Michael Foord225a0992010-02-18 20:30:09 +0000383 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000384 raise self.failureException(msg)
385
386 def assertTrue(self, expr, msg=None):
387 """Fail the test unless the expression is true."""
388 if not expr:
Michael Foord225a0992010-02-18 20:30:09 +0000389 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000390 raise self.failureException(msg)
391
392 def _formatMessage(self, msg, standardMsg):
393 """Honour the longMessage attribute when generating failure messages.
394 If longMessage is False this means:
395 * Use only an explicit message if it is provided
396 * Otherwise use the standard message for the assert
397
398 If longMessage is True:
399 * Use the standard message
400 * If an explicit message is provided, plus ' : ' and the explicit message
401 """
402 if not self.longMessage:
403 return msg or standardMsg
404 if msg is None:
405 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000406 try:
407 # don't switch to '{}' formatting in Python 2.X
408 # it changes the way unicode input is handled
409 return '%s : %s' % (standardMsg, msg)
410 except UnicodeDecodeError:
411 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000412
413
414 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
415 """Fail unless an exception of class excClass is thrown
416 by callableObj when invoked with arguments args and keyword
417 arguments kwargs. If a different type of exception is
418 thrown, it will not be caught, and the test case will be
419 deemed to have suffered an error, exactly as for an
420 unexpected exception.
421
422 If called with callableObj omitted or None, will return a
423 context object used like this::
424
Michael Foordd0edec32010-02-05 22:55:09 +0000425 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000426 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000427
428 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000429 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000430 exception after the assertion::
431
432 with self.assertRaises(SomeException) as cm:
433 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000434 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000435 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000436 """
437 context = _AssertRaisesContext(excClass, self)
438 if callableObj is None:
439 return context
440 with context:
441 callableObj(*args, **kwargs)
442
443 def _getAssertEqualityFunc(self, first, second):
444 """Get a detailed comparison function for the types of the two args.
445
446 Returns: A callable accepting (first, second, msg=None) that will
447 raise a failure exception if first != second with a useful human
448 readable error message for those types.
449 """
450 #
451 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
452 # and vice versa. I opted for the conservative approach in case
453 # subclasses are not intended to be compared in detail to their super
454 # class instances using a type equality func. This means testing
455 # subtypes won't automagically use the detailed comparison. Callers
456 # should use their type specific assertSpamEqual method to compare
457 # subclasses if the detailed comparison is desired and appropriate.
458 # See the discussion in http://bugs.python.org/issue2578.
459 #
460 if type(first) is type(second):
461 asserter = self._type_equality_funcs.get(type(first))
462 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000463 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000464
465 return self._baseAssertEqual
466
467 def _baseAssertEqual(self, first, second, msg=None):
468 """The default assertEqual implementation, not type specific."""
469 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000470 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000471 msg = self._formatMessage(msg, standardMsg)
472 raise self.failureException(msg)
473
474 def assertEqual(self, first, second, msg=None):
475 """Fail if the two objects are unequal as determined by the '=='
476 operator.
477 """
478 assertion_func = self._getAssertEqualityFunc(first, second)
479 assertion_func(first, second, msg=msg)
480
481 def assertNotEqual(self, first, second, msg=None):
482 """Fail if the two objects are equal as determined by the '=='
483 operator.
484 """
485 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000486 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
487 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000488 raise self.failureException(msg)
489
490 def assertAlmostEqual(self, first, second, places=7, msg=None):
491 """Fail if the two objects are unequal as determined by their
492 difference rounded to the given number of decimal places
493 (default 7) and comparing to zero.
494
495 Note that decimal places (from zero) are usually not the same
496 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000497
498 If the two objects compare equal then they will automatically
499 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000500 """
Michael Foordc3f79372009-09-13 16:40:02 +0000501 if first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000502 # shortcut for inf
Michael Foordc3f79372009-09-13 16:40:02 +0000503 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000504 if round(abs(second-first), places) != 0:
Michael Foord225a0992010-02-18 20:30:09 +0000505 standardMsg = '%s != %s within %r places' % (safe_repr(first),
506 safe_repr(second),
507 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000508 msg = self._formatMessage(msg, standardMsg)
509 raise self.failureException(msg)
510
511 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
512 """Fail if the two objects are equal as determined by their
513 difference rounded to the given number of decimal places
514 (default 7) and comparing to zero.
515
516 Note that decimal places (from zero) are usually not the same
517 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000518
519 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000520 """
Michael Foordc3f79372009-09-13 16:40:02 +0000521 if (first == second) or round(abs(second-first), places) == 0:
Michael Foord225a0992010-02-18 20:30:09 +0000522 standardMsg = '%s == %s within %r places' % (safe_repr(first),
523 safe_repr(second),
524 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000525 msg = self._formatMessage(msg, standardMsg)
526 raise self.failureException(msg)
527
528 # Synonyms for assertion methods
529
530 # The plurals are undocumented. Keep them that way to discourage use.
531 # Do not add more. Do not remove.
532 # Going through a deprecation cycle on these would annoy many people.
533 assertEquals = assertEqual
534 assertNotEquals = assertNotEqual
535 assertAlmostEquals = assertAlmostEqual
536 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000537 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000538
539 # These fail* assertion method names are pending deprecation and will
540 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
541 def _deprecate(original_func):
542 def deprecated_func(*args, **kwargs):
543 warnings.warn(
544 'Please use {0} instead.'.format(original_func.__name__),
545 PendingDeprecationWarning, 2)
546 return original_func(*args, **kwargs)
547 return deprecated_func
548
549 failUnlessEqual = _deprecate(assertEqual)
550 failIfEqual = _deprecate(assertNotEqual)
551 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
552 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
553 failUnless = _deprecate(assertTrue)
554 failUnlessRaises = _deprecate(assertRaises)
555 failIf = _deprecate(assertFalse)
556
557 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
558 """An equality assertion for ordered sequences (like lists and tuples).
559
R. David Murray05b41712010-01-29 19:35:39 +0000560 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000561 which can be indexed, has a length, and has an equality operator.
562
563 Args:
564 seq1: The first sequence to compare.
565 seq2: The second sequence to compare.
566 seq_type: The expected datatype of the sequences, or None if no
567 datatype should be enforced.
568 msg: Optional message to use on failure instead of a list of
569 differences.
570 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000571 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000572 seq_type_name = seq_type.__name__
573 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000574 raise self.failureException('First sequence is not a %s: %s'
575 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000576 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000577 raise self.failureException('Second sequence is not a %s: %s'
578 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000579 else:
580 seq_type_name = "sequence"
581
582 differing = None
583 try:
584 len1 = len(seq1)
585 except (TypeError, NotImplementedError):
586 differing = 'First %s has no length. Non-sequence?' % (
587 seq_type_name)
588
589 if differing is None:
590 try:
591 len2 = len(seq2)
592 except (TypeError, NotImplementedError):
593 differing = 'Second %s has no length. Non-sequence?' % (
594 seq_type_name)
595
596 if differing is None:
597 if seq1 == seq2:
598 return
599
Michael Foord225a0992010-02-18 20:30:09 +0000600 seq1_repr = safe_repr(seq1)
601 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000602 if len(seq1_repr) > 30:
603 seq1_repr = seq1_repr[:30] + '...'
604 if len(seq2_repr) > 30:
605 seq2_repr = seq2_repr[:30] + '...'
606 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
607 differing = '%ss differ: %s != %s\n' % elements
608
609 for i in xrange(min(len1, len2)):
610 try:
611 item1 = seq1[i]
612 except (TypeError, IndexError, NotImplementedError):
613 differing += ('\nUnable to index element %d of first %s\n' %
614 (i, seq_type_name))
615 break
616
617 try:
618 item2 = seq2[i]
619 except (TypeError, IndexError, NotImplementedError):
620 differing += ('\nUnable to index element %d of second %s\n' %
621 (i, seq_type_name))
622 break
623
624 if item1 != item2:
625 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
626 (i, item1, item2))
627 break
628 else:
629 if (len1 == len2 and seq_type is None and
630 type(seq1) != type(seq2)):
631 # The sequences are the same, but have differing types.
632 return
633
634 if len1 > len2:
635 differing += ('\nFirst %s contains %d additional '
636 'elements.\n' % (seq_type_name, len1 - len2))
637 try:
638 differing += ('First extra element %d:\n%s\n' %
639 (len2, seq1[len2]))
640 except (TypeError, IndexError, NotImplementedError):
641 differing += ('Unable to index element %d '
642 'of first %s\n' % (len2, seq_type_name))
643 elif len1 < len2:
644 differing += ('\nSecond %s contains %d additional '
645 'elements.\n' % (seq_type_name, len2 - len1))
646 try:
647 differing += ('First extra element %d:\n%s\n' %
648 (len1, seq2[len1]))
649 except (TypeError, IndexError, NotImplementedError):
650 differing += ('Unable to index element %d '
651 'of second %s\n' % (len1, seq_type_name))
Georg Brandl46cc46a2009-10-01 20:11:14 +0000652 standardMsg = differing + '\n' + '\n'.join(
653 difflib.ndiff(pprint.pformat(seq1).splitlines(),
654 pprint.pformat(seq2).splitlines()))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000655 msg = self._formatMessage(msg, standardMsg)
656 self.fail(msg)
657
658 def assertListEqual(self, list1, list2, msg=None):
659 """A list-specific equality assertion.
660
661 Args:
662 list1: The first list to compare.
663 list2: The second list to compare.
664 msg: Optional message to use on failure instead of a list of
665 differences.
666
667 """
668 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
669
670 def assertTupleEqual(self, tuple1, tuple2, msg=None):
671 """A tuple-specific equality assertion.
672
673 Args:
674 tuple1: The first tuple to compare.
675 tuple2: The second tuple to compare.
676 msg: Optional message to use on failure instead of a list of
677 differences.
678 """
679 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
680
681 def assertSetEqual(self, set1, set2, msg=None):
682 """A set-specific equality assertion.
683
684 Args:
685 set1: The first set to compare.
686 set2: The second set to compare.
687 msg: Optional message to use on failure instead of a list of
688 differences.
689
Michael Foord98e7b762010-03-20 03:00:34 +0000690 assertSetEqual uses ducktyping to support different types of sets, and
691 is optimized for sets specifically (parameters must support a
692 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000693 """
694 try:
695 difference1 = set1.difference(set2)
696 except TypeError, e:
697 self.fail('invalid type when attempting set difference: %s' % e)
698 except AttributeError, e:
699 self.fail('first argument does not support set difference: %s' % e)
700
701 try:
702 difference2 = set2.difference(set1)
703 except TypeError, e:
704 self.fail('invalid type when attempting set difference: %s' % e)
705 except AttributeError, e:
706 self.fail('second argument does not support set difference: %s' % e)
707
708 if not (difference1 or difference2):
709 return
710
711 lines = []
712 if difference1:
713 lines.append('Items in the first set but not the second:')
714 for item in difference1:
715 lines.append(repr(item))
716 if difference2:
717 lines.append('Items in the second set but not the first:')
718 for item in difference2:
719 lines.append(repr(item))
720
721 standardMsg = '\n'.join(lines)
722 self.fail(self._formatMessage(msg, standardMsg))
723
724 def assertIn(self, member, container, msg=None):
725 """Just like self.assertTrue(a in b), but with a nicer default message."""
726 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000727 standardMsg = '%s not found in %s' % (safe_repr(member),
728 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000729 self.fail(self._formatMessage(msg, standardMsg))
730
731 def assertNotIn(self, member, container, msg=None):
732 """Just like self.assertTrue(a not in b), but with a nicer default message."""
733 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000734 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
735 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000736 self.fail(self._formatMessage(msg, standardMsg))
737
738 def assertIs(self, expr1, expr2, msg=None):
739 """Just like self.assertTrue(a is b), but with a nicer default message."""
740 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000741 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000742 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000743 self.fail(self._formatMessage(msg, standardMsg))
744
745 def assertIsNot(self, expr1, expr2, msg=None):
746 """Just like self.assertTrue(a is not b), but with a nicer default message."""
747 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000748 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000749 self.fail(self._formatMessage(msg, standardMsg))
750
751 def assertDictEqual(self, d1, d2, msg=None):
752 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
753 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
754
755 if d1 != d2:
756 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
757 pprint.pformat(d1).splitlines(),
758 pprint.pformat(d2).splitlines())))
759 self.fail(self._formatMessage(msg, standardMsg))
760
761 def assertDictContainsSubset(self, expected, actual, msg=None):
762 """Checks whether actual is a superset of expected."""
763 missing = []
764 mismatched = []
765 for key, value in expected.iteritems():
766 if key not in actual:
767 missing.append(key)
768 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000769 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000770 (safe_repr(key), safe_repr(value),
771 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000772
773 if not (missing or mismatched):
774 return
775
776 standardMsg = ''
777 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000778 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
779 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000780 if mismatched:
781 if standardMsg:
782 standardMsg += '; '
783 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
784
785 self.fail(self._formatMessage(msg, standardMsg))
786
Michael Foord98e7b762010-03-20 03:00:34 +0000787 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
788 """An unordered sequence / set specific comparison. It asserts that
789 expected_seq and actual_seq contain the same elements. It is
790 the equivalent of::
791
792 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000793
794 Raises with an error message listing which elements of expected_seq
795 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000796
Michael Foord98e7b762010-03-20 03:00:34 +0000797 Asserts that each element has the same count in both sequences.
798 Example:
799 - [0, 1, 1] and [1, 0, 1] compare equal.
800 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000801 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000802 with warnings.catch_warnings():
803 if sys.py3kwarning:
804 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000805 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000806 "builtin_function_or_method order comparisons",
807 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000808 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000809 try:
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000810 expected = sorted(expected_seq)
811 actual = sorted(actual_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000812 except TypeError:
813 # Unsortable items (example: set(), complex(), ...)
814 expected = list(expected_seq)
815 actual = list(actual_seq)
816 missing, unexpected = unorderable_list_difference(
817 expected, actual, ignore_duplicate=False
818 )
819 else:
820 return self.assertSequenceEqual(expected, actual, msg=msg)
821
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000822 errors = []
823 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000824 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000825 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000826 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000827 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000828 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000829 if errors:
830 standardMsg = '\n'.join(errors)
831 self.fail(self._formatMessage(msg, standardMsg))
832
833 def assertMultiLineEqual(self, first, second, msg=None):
834 """Assert that two multi-line strings are equal."""
835 self.assert_(isinstance(first, basestring), (
836 'First argument is not a string'))
837 self.assert_(isinstance(second, basestring), (
838 'Second argument is not a string'))
839
840 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000841 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
842 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000843 self.fail(self._formatMessage(msg, standardMsg))
844
845 def assertLess(self, a, b, msg=None):
846 """Just like self.assertTrue(a < b), but with a nicer default message."""
847 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000848 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000849 self.fail(self._formatMessage(msg, standardMsg))
850
851 def assertLessEqual(self, a, b, msg=None):
852 """Just like self.assertTrue(a <= b), but with a nicer default message."""
853 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000854 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000855 self.fail(self._formatMessage(msg, standardMsg))
856
857 def assertGreater(self, a, b, msg=None):
858 """Just like self.assertTrue(a > b), but with a nicer default message."""
859 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000860 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000861 self.fail(self._formatMessage(msg, standardMsg))
862
863 def assertGreaterEqual(self, a, b, msg=None):
864 """Just like self.assertTrue(a >= b), but with a nicer default message."""
865 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000866 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000867 self.fail(self._formatMessage(msg, standardMsg))
868
869 def assertIsNone(self, obj, msg=None):
870 """Same as self.assertTrue(obj is None), with a nicer default message."""
871 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000872 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000873 self.fail(self._formatMessage(msg, standardMsg))
874
875 def assertIsNotNone(self, obj, msg=None):
876 """Included for symmetry with assertIsNone."""
877 if obj is None:
878 standardMsg = 'unexpectedly None'
879 self.fail(self._formatMessage(msg, standardMsg))
880
Georg Brandlf895cf52009-10-01 20:59:31 +0000881 def assertIsInstance(self, obj, cls, msg=None):
882 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
883 default message."""
884 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000885 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000886 self.fail(self._formatMessage(msg, standardMsg))
887
888 def assertNotIsInstance(self, obj, cls, msg=None):
889 """Included for symmetry with assertIsInstance."""
890 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000891 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000892 self.fail(self._formatMessage(msg, standardMsg))
893
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000894 def assertRaisesRegexp(self, expected_exception, expected_regexp,
895 callable_obj=None, *args, **kwargs):
896 """Asserts that the message in a raised exception matches a regexp.
897
898 Args:
899 expected_exception: Exception class expected to be raised.
900 expected_regexp: Regexp (re pattern object or string) expected
901 to be found in error message.
902 callable_obj: Function to be called.
903 args: Extra args.
904 kwargs: Extra kwargs.
905 """
906 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
907 if callable_obj is None:
908 return context
909 with context:
910 callable_obj(*args, **kwargs)
911
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000912 def assertRegexpMatches(self, text, expected_regexp, msg=None):
913 if isinstance(expected_regexp, basestring):
914 expected_regexp = re.compile(expected_regexp)
915 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000916 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000917 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000918 raise self.failureException(msg)
919
920
921class FunctionTestCase(TestCase):
922 """A test case that wraps a test function.
923
924 This is useful for slipping pre-existing test functions into the
925 unittest framework. Optionally, set-up and tidy-up functions can be
926 supplied. As with TestCase, the tidy-up ('tearDown') function will
927 always be called if the set-up ('setUp') function ran successfully.
928 """
929
930 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
931 super(FunctionTestCase, self).__init__()
932 self._setUpFunc = setUp
933 self._tearDownFunc = tearDown
934 self._testFunc = testFunc
935 self._description = description
936
937 def setUp(self):
938 if self._setUpFunc is not None:
939 self._setUpFunc()
940
941 def tearDown(self):
942 if self._tearDownFunc is not None:
943 self._tearDownFunc()
944
945 def runTest(self):
946 self._testFunc()
947
948 def id(self):
949 return self._testFunc.__name__
950
951 def __eq__(self, other):
952 if not isinstance(other, self.__class__):
953 return NotImplemented
954
955 return self._setUpFunc == other._setUpFunc and \
956 self._tearDownFunc == other._tearDownFunc and \
957 self._testFunc == other._testFunc and \
958 self._description == other._description
959
960 def __ne__(self, other):
961 return not self == other
962
963 def __hash__(self):
964 return hash((type(self), self._setUpFunc, self._tearDownFunc,
965 self._testFunc, self._description))
966
967 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000968 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000969 self._testFunc.__name__)
970
971 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000972 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000973 self._testFunc)
974
975 def shortDescription(self):
976 if self._description is not None:
977 return self._description
978 doc = self._testFunc.__doc__
979 return doc and doc.split("\n")[0].strip() or None