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