blob: aacd67ca087a8548c2cf8ee6758948854d540bb3 [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
11from .util import strclass, safe_repr, sorted_list_difference
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000012
13
14class SkipTest(Exception):
15 """
16 Raise this exception in a test to skip it.
17
18 Usually you can use TestResult.skip() or one of the skipping decorators
19 instead of raising this directly.
20 """
21 pass
22
23class _ExpectedFailure(Exception):
24 """
25 Raise this when a test is expected to fail.
26
27 This is an implementation detail.
28 """
29
30 def __init__(self, exc_info):
31 super(_ExpectedFailure, self).__init__()
32 self.exc_info = exc_info
33
34class _UnexpectedSuccess(Exception):
35 """
36 The test was supposed to fail, but it didn't!
37 """
38 pass
39
40def _id(obj):
41 return obj
42
43def skip(reason):
44 """
45 Unconditionally skip a test.
46 """
47 def decorator(test_item):
48 if isinstance(test_item, type) and issubclass(test_item, TestCase):
49 test_item.__unittest_skip__ = True
50 test_item.__unittest_skip_why__ = reason
51 return test_item
52 @functools.wraps(test_item)
53 def skip_wrapper(*args, **kwargs):
54 raise SkipTest(reason)
55 return skip_wrapper
56 return decorator
57
58def skipIf(condition, reason):
59 """
60 Skip a test if the condition is true.
61 """
62 if condition:
63 return skip(reason)
64 return _id
65
66def skipUnless(condition, reason):
67 """
68 Skip a test unless the condition is true.
69 """
70 if not condition:
71 return skip(reason)
72 return _id
73
74
75def expectedFailure(func):
76 @functools.wraps(func)
77 def wrapper(*args, **kwargs):
78 try:
79 func(*args, **kwargs)
80 except Exception:
81 raise _ExpectedFailure(sys.exc_info())
82 raise _UnexpectedSuccess
83 return wrapper
84
85
86class _AssertRaisesContext(object):
87 """A context manager used to implement TestCase.assertRaises* methods."""
88
89 def __init__(self, expected, test_case, expected_regexp=None):
90 self.expected = expected
91 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +000092 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000093
94 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +000095 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000096
97 def __exit__(self, exc_type, exc_value, tb):
98 if exc_type is None:
99 try:
100 exc_name = self.expected.__name__
101 except AttributeError:
102 exc_name = str(self.expected)
103 raise self.failureException(
104 "{0} not raised".format(exc_name))
105 if not issubclass(exc_type, self.expected):
106 # let unexpected exceptions pass through
107 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000108 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000109 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000110 return True
111
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000112 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000113 if isinstance(expected_regexp, basestring):
114 expected_regexp = re.compile(expected_regexp)
115 if not expected_regexp.search(str(exc_value)):
116 raise self.failureException('"%s" does not match "%s"' %
117 (expected_regexp.pattern, str(exc_value)))
118 return True
119
120
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000121class TestCase(object):
122 """A class whose instances are single test cases.
123
124 By default, the test code itself should be placed in a method named
125 'runTest'.
126
127 If the fixture may be used for many test cases, create as
128 many test methods as are needed. When instantiating such a TestCase
129 subclass, specify in the constructor arguments the name of the test method
130 that the instance is to execute.
131
132 Test authors should subclass TestCase for their own tests. Construction
133 and deconstruction of the test's environment ('fixture') can be
134 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
135
136 If it is necessary to override the __init__ method, the base class
137 __init__ method must always be called. It is important that subclasses
138 should not change the signature of their __init__ method, since instances
139 of the classes are instantiated automatically by parts of the framework
140 in order to be run.
141 """
142
143 # This attribute determines which exception will be raised when
144 # the instance's assertion methods fail; test methods raising this
145 # exception will be deemed to have 'failed' rather than 'errored'
146
147 failureException = AssertionError
148
149 # This attribute determines whether long messages (including repr of
150 # objects used in assert methods) will be printed on failure in *addition*
151 # to any explicit message passed.
152
153 longMessage = False
154
155
156 def __init__(self, methodName='runTest'):
157 """Create an instance of the class that will use the named test
158 method when executed. Raises a ValueError if the instance does
159 not have a method with the specified name.
160 """
161 self._testMethodName = methodName
162 self._resultForDoCleanups = None
163 try:
164 testMethod = getattr(self, methodName)
165 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000166 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000167 (self.__class__, methodName))
168 self._testMethodDoc = testMethod.__doc__
169 self._cleanups = []
170
171 # Map types to custom assertEqual functions that will compare
172 # instances of said type in more detail to generate a more useful
173 # error message.
174 self._type_equality_funcs = {}
175 self.addTypeEqualityFunc(dict, self.assertDictEqual)
176 self.addTypeEqualityFunc(list, self.assertListEqual)
177 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
178 self.addTypeEqualityFunc(set, self.assertSetEqual)
179 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foordfe6349c2010-02-08 22:41:16 +0000180 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000181
182 def addTypeEqualityFunc(self, typeobj, function):
183 """Add a type specific assertEqual style function to compare a type.
184
185 This method is for use by TestCase subclasses that need to register
186 their own type equality functions to provide nicer error messages.
187
188 Args:
189 typeobj: The data type to call this function on when both values
190 are of the same type in assertEqual().
191 function: The callable taking two arguments and an optional
192 msg= argument that raises self.failureException with a
193 useful error message when the two arguments are not equal.
194 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000195 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000196
197 def addCleanup(self, function, *args, **kwargs):
198 """Add a function, with arguments, to be called when the test is
199 completed. Functions added are called on a LIFO basis and are
200 called after tearDown on test failure or success.
201
202 Cleanup items are called even if setUp fails (unlike tearDown)."""
203 self._cleanups.append((function, args, kwargs))
204
205 def setUp(self):
206 "Hook method for setting up the test fixture before exercising it."
207 pass
208
209 def tearDown(self):
210 "Hook method for deconstructing the test fixture after testing it."
211 pass
212
213 def countTestCases(self):
214 return 1
215
216 def defaultTestResult(self):
217 return result.TestResult()
218
219 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000220 """Returns a one-line description of the test, or None if no
221 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000222
Michael Foorddb43b5a2010-02-10 14:25:12 +0000223 The default implementation of this method returns the first line of
224 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000225 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000226 doc = self._testMethodDoc
227 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000228
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000229
230 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000231 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000232
233 def __eq__(self, other):
234 if type(self) is not type(other):
235 return NotImplemented
236
237 return self._testMethodName == other._testMethodName
238
239 def __ne__(self, other):
240 return not self == other
241
242 def __hash__(self):
243 return hash((type(self), self._testMethodName))
244
245 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000246 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000247
248 def __repr__(self):
249 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000250 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000251
Michael Foordae3db0a2010-02-22 23:28:32 +0000252 def _addSkip(self, result, reason):
253 addSkip = getattr(result, 'addSkip', None)
254 if addSkip is not None:
255 addSkip(self, reason)
256 else:
257 warnings.warn("TestResult has no addSkip method, skips not reported",
258 RuntimeWarning, 2)
259 result.addSuccess(self)
260
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000261 def run(self, result=None):
262 orig_result = result
263 if result is None:
264 result = self.defaultTestResult()
265 startTestRun = getattr(result, 'startTestRun', None)
266 if startTestRun is not None:
267 startTestRun()
268
269 self._resultForDoCleanups = result
270 result.startTest(self)
271 if getattr(self.__class__, "__unittest_skip__", False):
272 # If the whole class was skipped.
273 try:
Michael Foordae3db0a2010-02-22 23:28:32 +0000274 self._addSkip(result, self.__class__.__unittest_skip_why__)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000275 finally:
276 result.stopTest(self)
277 return
278 testMethod = getattr(self, self._testMethodName)
279 try:
280 success = False
281 try:
282 self.setUp()
283 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000284 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000285 except Exception:
286 result.addError(self, sys.exc_info())
287 else:
288 try:
289 testMethod()
290 except self.failureException:
291 result.addFailure(self, sys.exc_info())
292 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000293 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
294 if addExpectedFailure is not None:
295 addExpectedFailure(self, e.exc_info)
296 else:
297 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
298 RuntimeWarning)
299 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000300 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000301 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
302 if addUnexpectedSuccess is not None:
303 addUnexpectedSuccess(self)
304 else:
305 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
306 RuntimeWarning)
307 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000308 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000309 self._addSkip(result, str(e))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000310 except Exception:
311 result.addError(self, sys.exc_info())
312 else:
313 success = True
314
315 try:
316 self.tearDown()
317 except Exception:
318 result.addError(self, sys.exc_info())
319 success = False
320
321 cleanUpSuccess = self.doCleanups()
322 success = success and cleanUpSuccess
323 if success:
324 result.addSuccess(self)
325 finally:
326 result.stopTest(self)
327 if orig_result is None:
328 stopTestRun = getattr(result, 'stopTestRun', None)
329 if stopTestRun is not None:
330 stopTestRun()
331
332 def doCleanups(self):
333 """Execute all cleanup functions. Normally called for you after
334 tearDown."""
335 result = self._resultForDoCleanups
336 ok = True
337 while self._cleanups:
338 function, args, kwargs = self._cleanups.pop(-1)
339 try:
340 function(*args, **kwargs)
341 except Exception:
342 ok = False
343 result.addError(self, sys.exc_info())
344 return ok
345
346 def __call__(self, *args, **kwds):
347 return self.run(*args, **kwds)
348
349 def debug(self):
350 """Run the test without collecting errors in a TestResult"""
351 self.setUp()
352 getattr(self, self._testMethodName)()
353 self.tearDown()
354
355 def skipTest(self, reason):
356 """Skip this test."""
357 raise SkipTest(reason)
358
359 def fail(self, msg=None):
360 """Fail immediately, with the given message."""
361 raise self.failureException(msg)
362
363 def assertFalse(self, expr, msg=None):
364 "Fail the test if the expression is true."
365 if expr:
Michael Foord225a0992010-02-18 20:30:09 +0000366 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000367 raise self.failureException(msg)
368
369 def assertTrue(self, expr, msg=None):
370 """Fail the test unless the expression is true."""
371 if not expr:
Michael Foord225a0992010-02-18 20:30:09 +0000372 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000373 raise self.failureException(msg)
374
375 def _formatMessage(self, msg, standardMsg):
376 """Honour the longMessage attribute when generating failure messages.
377 If longMessage is False this means:
378 * Use only an explicit message if it is provided
379 * Otherwise use the standard message for the assert
380
381 If longMessage is True:
382 * Use the standard message
383 * If an explicit message is provided, plus ' : ' and the explicit message
384 """
385 if not self.longMessage:
386 return msg or standardMsg
387 if msg is None:
388 return standardMsg
389 return standardMsg + ' : ' + msg
390
391
392 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
393 """Fail unless an exception of class excClass is thrown
394 by callableObj when invoked with arguments args and keyword
395 arguments kwargs. If a different type of exception is
396 thrown, it will not be caught, and the test case will be
397 deemed to have suffered an error, exactly as for an
398 unexpected exception.
399
400 If called with callableObj omitted or None, will return a
401 context object used like this::
402
Michael Foordd0edec32010-02-05 22:55:09 +0000403 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000404 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000405
406 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000407 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000408 exception after the assertion::
409
410 with self.assertRaises(SomeException) as cm:
411 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000412 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000413 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000414 """
415 context = _AssertRaisesContext(excClass, self)
416 if callableObj is None:
417 return context
418 with context:
419 callableObj(*args, **kwargs)
420
421 def _getAssertEqualityFunc(self, first, second):
422 """Get a detailed comparison function for the types of the two args.
423
424 Returns: A callable accepting (first, second, msg=None) that will
425 raise a failure exception if first != second with a useful human
426 readable error message for those types.
427 """
428 #
429 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
430 # and vice versa. I opted for the conservative approach in case
431 # subclasses are not intended to be compared in detail to their super
432 # class instances using a type equality func. This means testing
433 # subtypes won't automagically use the detailed comparison. Callers
434 # should use their type specific assertSpamEqual method to compare
435 # subclasses if the detailed comparison is desired and appropriate.
436 # See the discussion in http://bugs.python.org/issue2578.
437 #
438 if type(first) is type(second):
439 asserter = self._type_equality_funcs.get(type(first))
440 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000441 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000442
443 return self._baseAssertEqual
444
445 def _baseAssertEqual(self, first, second, msg=None):
446 """The default assertEqual implementation, not type specific."""
447 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000448 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000449 msg = self._formatMessage(msg, standardMsg)
450 raise self.failureException(msg)
451
452 def assertEqual(self, first, second, msg=None):
453 """Fail if the two objects are unequal as determined by the '=='
454 operator.
455 """
456 assertion_func = self._getAssertEqualityFunc(first, second)
457 assertion_func(first, second, msg=msg)
458
459 def assertNotEqual(self, first, second, msg=None):
460 """Fail if the two objects are equal as determined by the '=='
461 operator.
462 """
463 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000464 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
465 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000466 raise self.failureException(msg)
467
468 def assertAlmostEqual(self, first, second, places=7, msg=None):
469 """Fail if the two objects are unequal as determined by their
470 difference rounded to the given number of decimal places
471 (default 7) and comparing to zero.
472
473 Note that decimal places (from zero) are usually not the same
474 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000475
476 If the two objects compare equal then they will automatically
477 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000478 """
Michael Foordc3f79372009-09-13 16:40:02 +0000479 if first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000480 # shortcut for inf
Michael Foordc3f79372009-09-13 16:40:02 +0000481 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000482 if round(abs(second-first), places) != 0:
Michael Foord225a0992010-02-18 20:30:09 +0000483 standardMsg = '%s != %s within %r places' % (safe_repr(first),
484 safe_repr(second),
485 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000486 msg = self._formatMessage(msg, standardMsg)
487 raise self.failureException(msg)
488
489 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
490 """Fail if the two objects are equal as determined by their
491 difference rounded to the given number of decimal places
492 (default 7) and comparing to zero.
493
494 Note that decimal places (from zero) are usually not the same
495 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000496
497 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000498 """
Michael Foordc3f79372009-09-13 16:40:02 +0000499 if (first == second) or round(abs(second-first), places) == 0:
Michael Foord225a0992010-02-18 20:30:09 +0000500 standardMsg = '%s == %s within %r places' % (safe_repr(first),
501 safe_repr(second),
502 places)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000503 msg = self._formatMessage(msg, standardMsg)
504 raise self.failureException(msg)
505
506 # Synonyms for assertion methods
507
508 # The plurals are undocumented. Keep them that way to discourage use.
509 # Do not add more. Do not remove.
510 # Going through a deprecation cycle on these would annoy many people.
511 assertEquals = assertEqual
512 assertNotEquals = assertNotEqual
513 assertAlmostEquals = assertAlmostEqual
514 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000515 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000516
517 # These fail* assertion method names are pending deprecation and will
518 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
519 def _deprecate(original_func):
520 def deprecated_func(*args, **kwargs):
521 warnings.warn(
522 'Please use {0} instead.'.format(original_func.__name__),
523 PendingDeprecationWarning, 2)
524 return original_func(*args, **kwargs)
525 return deprecated_func
526
527 failUnlessEqual = _deprecate(assertEqual)
528 failIfEqual = _deprecate(assertNotEqual)
529 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
530 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
531 failUnless = _deprecate(assertTrue)
532 failUnlessRaises = _deprecate(assertRaises)
533 failIf = _deprecate(assertFalse)
534
535 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
536 """An equality assertion for ordered sequences (like lists and tuples).
537
R. David Murray05b41712010-01-29 19:35:39 +0000538 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000539 which can be indexed, has a length, and has an equality operator.
540
541 Args:
542 seq1: The first sequence to compare.
543 seq2: The second sequence to compare.
544 seq_type: The expected datatype of the sequences, or None if no
545 datatype should be enforced.
546 msg: Optional message to use on failure instead of a list of
547 differences.
548 """
549 if seq_type != None:
550 seq_type_name = seq_type.__name__
551 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000552 raise self.failureException('First sequence is not a %s: %s'
553 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000554 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000555 raise self.failureException('Second sequence is not a %s: %s'
556 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000557 else:
558 seq_type_name = "sequence"
559
560 differing = None
561 try:
562 len1 = len(seq1)
563 except (TypeError, NotImplementedError):
564 differing = 'First %s has no length. Non-sequence?' % (
565 seq_type_name)
566
567 if differing is None:
568 try:
569 len2 = len(seq2)
570 except (TypeError, NotImplementedError):
571 differing = 'Second %s has no length. Non-sequence?' % (
572 seq_type_name)
573
574 if differing is None:
575 if seq1 == seq2:
576 return
577
Michael Foord225a0992010-02-18 20:30:09 +0000578 seq1_repr = safe_repr(seq1)
579 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000580 if len(seq1_repr) > 30:
581 seq1_repr = seq1_repr[:30] + '...'
582 if len(seq2_repr) > 30:
583 seq2_repr = seq2_repr[:30] + '...'
584 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
585 differing = '%ss differ: %s != %s\n' % elements
586
587 for i in xrange(min(len1, len2)):
588 try:
589 item1 = seq1[i]
590 except (TypeError, IndexError, NotImplementedError):
591 differing += ('\nUnable to index element %d of first %s\n' %
592 (i, seq_type_name))
593 break
594
595 try:
596 item2 = seq2[i]
597 except (TypeError, IndexError, NotImplementedError):
598 differing += ('\nUnable to index element %d of second %s\n' %
599 (i, seq_type_name))
600 break
601
602 if item1 != item2:
603 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
604 (i, item1, item2))
605 break
606 else:
607 if (len1 == len2 and seq_type is None and
608 type(seq1) != type(seq2)):
609 # The sequences are the same, but have differing types.
610 return
611
612 if len1 > len2:
613 differing += ('\nFirst %s contains %d additional '
614 'elements.\n' % (seq_type_name, len1 - len2))
615 try:
616 differing += ('First extra element %d:\n%s\n' %
617 (len2, seq1[len2]))
618 except (TypeError, IndexError, NotImplementedError):
619 differing += ('Unable to index element %d '
620 'of first %s\n' % (len2, seq_type_name))
621 elif len1 < len2:
622 differing += ('\nSecond %s contains %d additional '
623 'elements.\n' % (seq_type_name, len2 - len1))
624 try:
625 differing += ('First extra element %d:\n%s\n' %
626 (len1, seq2[len1]))
627 except (TypeError, IndexError, NotImplementedError):
628 differing += ('Unable to index element %d '
629 'of second %s\n' % (len1, seq_type_name))
Georg Brandl46cc46a2009-10-01 20:11:14 +0000630 standardMsg = differing + '\n' + '\n'.join(
631 difflib.ndiff(pprint.pformat(seq1).splitlines(),
632 pprint.pformat(seq2).splitlines()))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000633 msg = self._formatMessage(msg, standardMsg)
634 self.fail(msg)
635
636 def assertListEqual(self, list1, list2, msg=None):
637 """A list-specific equality assertion.
638
639 Args:
640 list1: The first list to compare.
641 list2: The second list to compare.
642 msg: Optional message to use on failure instead of a list of
643 differences.
644
645 """
646 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
647
648 def assertTupleEqual(self, tuple1, tuple2, msg=None):
649 """A tuple-specific equality assertion.
650
651 Args:
652 tuple1: The first tuple to compare.
653 tuple2: The second tuple to compare.
654 msg: Optional message to use on failure instead of a list of
655 differences.
656 """
657 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
658
659 def assertSetEqual(self, set1, set2, msg=None):
660 """A set-specific equality assertion.
661
662 Args:
663 set1: The first set to compare.
664 set2: The second set to compare.
665 msg: Optional message to use on failure instead of a list of
666 differences.
667
668 For more general containership equality, assertSameElements will work
669 with things other than sets. This uses ducktyping to support
670 different types of sets, and is optimized for sets specifically
671 (parameters must support a difference method).
672 """
673 try:
674 difference1 = set1.difference(set2)
675 except TypeError, e:
676 self.fail('invalid type when attempting set difference: %s' % e)
677 except AttributeError, e:
678 self.fail('first argument does not support set difference: %s' % e)
679
680 try:
681 difference2 = set2.difference(set1)
682 except TypeError, e:
683 self.fail('invalid type when attempting set difference: %s' % e)
684 except AttributeError, e:
685 self.fail('second argument does not support set difference: %s' % e)
686
687 if not (difference1 or difference2):
688 return
689
690 lines = []
691 if difference1:
692 lines.append('Items in the first set but not the second:')
693 for item in difference1:
694 lines.append(repr(item))
695 if difference2:
696 lines.append('Items in the second set but not the first:')
697 for item in difference2:
698 lines.append(repr(item))
699
700 standardMsg = '\n'.join(lines)
701 self.fail(self._formatMessage(msg, standardMsg))
702
703 def assertIn(self, member, container, msg=None):
704 """Just like self.assertTrue(a in b), but with a nicer default message."""
705 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000706 standardMsg = '%s not found in %s' % (safe_repr(member),
707 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000708 self.fail(self._formatMessage(msg, standardMsg))
709
710 def assertNotIn(self, member, container, msg=None):
711 """Just like self.assertTrue(a not in b), but with a nicer default message."""
712 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000713 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
714 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000715 self.fail(self._formatMessage(msg, standardMsg))
716
717 def assertIs(self, expr1, expr2, msg=None):
718 """Just like self.assertTrue(a is b), but with a nicer default message."""
719 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000720 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000721 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000722 self.fail(self._formatMessage(msg, standardMsg))
723
724 def assertIsNot(self, expr1, expr2, msg=None):
725 """Just like self.assertTrue(a is not b), but with a nicer default message."""
726 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000727 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000728 self.fail(self._formatMessage(msg, standardMsg))
729
730 def assertDictEqual(self, d1, d2, msg=None):
731 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
732 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
733
734 if d1 != d2:
735 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
736 pprint.pformat(d1).splitlines(),
737 pprint.pformat(d2).splitlines())))
738 self.fail(self._formatMessage(msg, standardMsg))
739
740 def assertDictContainsSubset(self, expected, actual, msg=None):
741 """Checks whether actual is a superset of expected."""
742 missing = []
743 mismatched = []
744 for key, value in expected.iteritems():
745 if key not in actual:
746 missing.append(key)
747 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000748 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000749 (safe_repr(key), safe_repr(value),
750 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000751
752 if not (missing or mismatched):
753 return
754
755 standardMsg = ''
756 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000757 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
758 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000759 if mismatched:
760 if standardMsg:
761 standardMsg += '; '
762 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
763
764 self.fail(self._formatMessage(msg, standardMsg))
765
766 def assertSameElements(self, expected_seq, actual_seq, msg=None):
767 """An unordered sequence specific comparison.
768
769 Raises with an error message listing which elements of expected_seq
770 are missing from actual_seq and vice versa if any.
Michael Foordd0edec32010-02-05 22:55:09 +0000771
772 Duplicate elements are ignored when comparing *expected_seq* and
773 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
774 set(actual))`` but it works with sequences of unhashable objects as
775 well.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000776 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000777 with warnings.catch_warnings():
778 if sys.py3kwarning:
779 # Silence Py3k warning raised during the sorting
780 for msg in ["dict inequality comparisons",
781 "builtin_function_or_method order comparisons",
782 "comparing unequal types"]:
783 warnings.filterwarnings("ignore", msg, DeprecationWarning)
784 try:
785 expected = set(expected_seq)
786 actual = set(actual_seq)
787 missing = sorted(expected.difference(actual))
788 unexpected = sorted(actual.difference(expected))
789 except TypeError:
790 # Fall back to slower list-compare if any of the objects are
791 # not hashable.
792 expected = sorted(expected_seq)
793 actual = sorted(actual_seq)
Michael Foord225a0992010-02-18 20:30:09 +0000794 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000795 errors = []
796 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000797 errors.append('Expected, but missing:\n %s' %
798 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000799 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000800 errors.append('Unexpected, but present:\n %s' %
801 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000802 if errors:
803 standardMsg = '\n'.join(errors)
804 self.fail(self._formatMessage(msg, standardMsg))
805
806 def assertMultiLineEqual(self, first, second, msg=None):
807 """Assert that two multi-line strings are equal."""
808 self.assert_(isinstance(first, basestring), (
809 'First argument is not a string'))
810 self.assert_(isinstance(second, basestring), (
811 'Second argument is not a string'))
812
813 if first != second:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000814 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
815 second.splitlines(True)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000816 self.fail(self._formatMessage(msg, standardMsg))
817
818 def assertLess(self, a, b, msg=None):
819 """Just like self.assertTrue(a < b), but with a nicer default message."""
820 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000821 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000822 self.fail(self._formatMessage(msg, standardMsg))
823
824 def assertLessEqual(self, a, b, msg=None):
825 """Just like self.assertTrue(a <= b), but with a nicer default message."""
826 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000827 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000828 self.fail(self._formatMessage(msg, standardMsg))
829
830 def assertGreater(self, a, b, msg=None):
831 """Just like self.assertTrue(a > b), but with a nicer default message."""
832 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000833 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000834 self.fail(self._formatMessage(msg, standardMsg))
835
836 def assertGreaterEqual(self, a, b, msg=None):
837 """Just like self.assertTrue(a >= b), but with a nicer default message."""
838 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000839 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000840 self.fail(self._formatMessage(msg, standardMsg))
841
842 def assertIsNone(self, obj, msg=None):
843 """Same as self.assertTrue(obj is None), with a nicer default message."""
844 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000845 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000846 self.fail(self._formatMessage(msg, standardMsg))
847
848 def assertIsNotNone(self, obj, msg=None):
849 """Included for symmetry with assertIsNone."""
850 if obj is None:
851 standardMsg = 'unexpectedly None'
852 self.fail(self._formatMessage(msg, standardMsg))
853
Georg Brandlf895cf52009-10-01 20:59:31 +0000854 def assertIsInstance(self, obj, cls, msg=None):
855 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
856 default message."""
857 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000858 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000859 self.fail(self._formatMessage(msg, standardMsg))
860
861 def assertNotIsInstance(self, obj, cls, msg=None):
862 """Included for symmetry with assertIsInstance."""
863 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000864 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000865 self.fail(self._formatMessage(msg, standardMsg))
866
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000867 def assertRaisesRegexp(self, expected_exception, expected_regexp,
868 callable_obj=None, *args, **kwargs):
869 """Asserts that the message in a raised exception matches a regexp.
870
871 Args:
872 expected_exception: Exception class expected to be raised.
873 expected_regexp: Regexp (re pattern object or string) expected
874 to be found in error message.
875 callable_obj: Function to be called.
876 args: Extra args.
877 kwargs: Extra kwargs.
878 """
879 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
880 if callable_obj is None:
881 return context
882 with context:
883 callable_obj(*args, **kwargs)
884
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000885 def assertRegexpMatches(self, text, expected_regexp, msg=None):
886 if isinstance(expected_regexp, basestring):
887 expected_regexp = re.compile(expected_regexp)
888 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000889 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000890 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000891 raise self.failureException(msg)
892
893
894class FunctionTestCase(TestCase):
895 """A test case that wraps a test function.
896
897 This is useful for slipping pre-existing test functions into the
898 unittest framework. Optionally, set-up and tidy-up functions can be
899 supplied. As with TestCase, the tidy-up ('tearDown') function will
900 always be called if the set-up ('setUp') function ran successfully.
901 """
902
903 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
904 super(FunctionTestCase, self).__init__()
905 self._setUpFunc = setUp
906 self._tearDownFunc = tearDown
907 self._testFunc = testFunc
908 self._description = description
909
910 def setUp(self):
911 if self._setUpFunc is not None:
912 self._setUpFunc()
913
914 def tearDown(self):
915 if self._tearDownFunc is not None:
916 self._tearDownFunc()
917
918 def runTest(self):
919 self._testFunc()
920
921 def id(self):
922 return self._testFunc.__name__
923
924 def __eq__(self, other):
925 if not isinstance(other, self.__class__):
926 return NotImplemented
927
928 return self._setUpFunc == other._setUpFunc and \
929 self._tearDownFunc == other._tearDownFunc and \
930 self._testFunc == other._testFunc and \
931 self._description == other._description
932
933 def __ne__(self, other):
934 return not self == other
935
936 def __hash__(self):
937 return hash((type(self), self._setUpFunc, self._tearDownFunc,
938 self._testFunc, self._description))
939
940 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000941 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000942 self._testFunc.__name__)
943
944 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000945 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000946 self._testFunc)
947
948 def shortDescription(self):
949 if self._description is not None:
950 return self._description
951 doc = self._testFunc.__doc__
952 return doc and doc.split("\n")[0].strip() or None