Issue #3366: Add gamma function to math module.
[python.git] / Lib / unittest / case.py
blobcac28421bf7c70a51ec87f419e5eeb314fa9da21
1 """Test case implementation"""
3 import sys
4 import functools
5 import difflib
6 import pprint
7 import re
8 import warnings
10 from . import result, util
13 class SkipTest(Exception):
14 """
15 Raise this exception in a test to skip it.
17 Usually you can use TestResult.skip() or one of the skipping decorators
18 instead of raising this directly.
19 """
20 pass
22 class _ExpectedFailure(Exception):
23 """
24 Raise this when a test is expected to fail.
26 This is an implementation detail.
27 """
29 def __init__(self, exc_info):
30 super(_ExpectedFailure, self).__init__()
31 self.exc_info = exc_info
33 class _UnexpectedSuccess(Exception):
34 """
35 The test was supposed to fail, but it didn't!
36 """
37 pass
39 def _id(obj):
40 return obj
42 def 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
57 def skipIf(condition, reason):
58 """
59 Skip a test if the condition is true.
60 """
61 if condition:
62 return skip(reason)
63 return _id
65 def 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
74 def 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
85 class _AssertRaisesContext(object):
86 """A context manager used to implement TestCase.assertRaises* methods."""
88 def __init__(self, expected, test_case, expected_regexp=None):
89 self.expected = expected
90 self.failureException = test_case.failureException
91 self.expected_regex = expected_regexp
93 def __enter__(self):
94 pass
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
107 self.exc_value = exc_value #store for later retrieval
108 if self.expected_regex is None:
109 return True
111 expected_regexp = self.expected_regex
112 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
120 class _AssertWrapper(object):
121 """Wrap entries in the _type_equality_funcs registry to make them deep
122 copyable."""
124 def __init__(self, function):
125 self.function = function
127 def __deepcopy__(self, memo):
128 memo[id(self)] = self
131 class TestCase(object):
132 """A class whose instances are single test cases.
134 By default, the test code itself should be placed in a method named
135 'runTest'.
137 If the fixture may be used for many test cases, create as
138 many test methods as are needed. When instantiating such a TestCase
139 subclass, specify in the constructor arguments the name of the test method
140 that the instance is to execute.
142 Test authors should subclass TestCase for their own tests. Construction
143 and deconstruction of the test's environment ('fixture') can be
144 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
146 If it is necessary to override the __init__ method, the base class
147 __init__ method must always be called. It is important that subclasses
148 should not change the signature of their __init__ method, since instances
149 of the classes are instantiated automatically by parts of the framework
150 in order to be run.
153 # This attribute determines which exception will be raised when
154 # the instance's assertion methods fail; test methods raising this
155 # exception will be deemed to have 'failed' rather than 'errored'
157 failureException = AssertionError
159 # This attribute determines whether long messages (including repr of
160 # objects used in assert methods) will be printed on failure in *addition*
161 # to any explicit message passed.
163 longMessage = False
166 def __init__(self, methodName='runTest'):
167 """Create an instance of the class that will use the named test
168 method when executed. Raises a ValueError if the instance does
169 not have a method with the specified name.
171 self._testMethodName = methodName
172 self._resultForDoCleanups = None
173 try:
174 testMethod = getattr(self, methodName)
175 except AttributeError:
176 raise ValueError("no such test method in %s: %s" % \
177 (self.__class__, methodName))
178 self._testMethodDoc = testMethod.__doc__
179 self._cleanups = []
181 # Map types to custom assertEqual functions that will compare
182 # instances of said type in more detail to generate a more useful
183 # error message.
184 self._type_equality_funcs = {}
185 self.addTypeEqualityFunc(dict, self.assertDictEqual)
186 self.addTypeEqualityFunc(list, self.assertListEqual)
187 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
188 self.addTypeEqualityFunc(set, self.assertSetEqual)
189 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
191 def addTypeEqualityFunc(self, typeobj, function):
192 """Add a type specific assertEqual style function to compare a type.
194 This method is for use by TestCase subclasses that need to register
195 their own type equality functions to provide nicer error messages.
197 Args:
198 typeobj: The data type to call this function on when both values
199 are of the same type in assertEqual().
200 function: The callable taking two arguments and an optional
201 msg= argument that raises self.failureException with a
202 useful error message when the two arguments are not equal.
204 self._type_equality_funcs[typeobj] = _AssertWrapper(function)
206 def addCleanup(self, function, *args, **kwargs):
207 """Add a function, with arguments, to be called when the test is
208 completed. Functions added are called on a LIFO basis and are
209 called after tearDown on test failure or success.
211 Cleanup items are called even if setUp fails (unlike tearDown)."""
212 self._cleanups.append((function, args, kwargs))
214 def setUp(self):
215 "Hook method for setting up the test fixture before exercising it."
216 pass
218 def tearDown(self):
219 "Hook method for deconstructing the test fixture after testing it."
220 pass
222 def countTestCases(self):
223 return 1
225 def defaultTestResult(self):
226 return result.TestResult()
228 def shortDescription(self):
229 """Returns both the test method name and first line of its docstring.
231 If no docstring is given, only returns the method name.
233 This method overrides unittest.TestCase.shortDescription(), which
234 only returns the first line of the docstring, obscuring the name
235 of the test upon failure.
237 desc = str(self)
238 doc_first_line = None
240 if self._testMethodDoc:
241 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
242 if doc_first_line:
243 desc = '\n'.join((desc, doc_first_line))
244 return desc
246 def id(self):
247 return "%s.%s" % (util.strclass(self.__class__), self._testMethodName)
249 def __eq__(self, other):
250 if type(self) is not type(other):
251 return NotImplemented
253 return self._testMethodName == other._testMethodName
255 def __ne__(self, other):
256 return not self == other
258 def __hash__(self):
259 return hash((type(self), self._testMethodName))
261 def __str__(self):
262 return "%s (%s)" % (self._testMethodName, util.strclass(self.__class__))
264 def __repr__(self):
265 return "<%s testMethod=%s>" % \
266 (util.strclass(self.__class__), self._testMethodName)
268 def run(self, result=None):
269 orig_result = result
270 if result is None:
271 result = self.defaultTestResult()
272 startTestRun = getattr(result, 'startTestRun', None)
273 if startTestRun is not None:
274 startTestRun()
276 self._resultForDoCleanups = result
277 result.startTest(self)
278 if getattr(self.__class__, "__unittest_skip__", False):
279 # If the whole class was skipped.
280 try:
281 result.addSkip(self, self.__class__.__unittest_skip_why__)
282 finally:
283 result.stopTest(self)
284 return
285 testMethod = getattr(self, self._testMethodName)
286 try:
287 success = False
288 try:
289 self.setUp()
290 except SkipTest as e:
291 result.addSkip(self, str(e))
292 except Exception:
293 result.addError(self, sys.exc_info())
294 else:
295 try:
296 testMethod()
297 except self.failureException:
298 result.addFailure(self, sys.exc_info())
299 except _ExpectedFailure as e:
300 result.addExpectedFailure(self, e.exc_info)
301 except _UnexpectedSuccess:
302 result.addUnexpectedSuccess(self)
303 except SkipTest as e:
304 result.addSkip(self, str(e))
305 except Exception:
306 result.addError(self, sys.exc_info())
307 else:
308 success = True
310 try:
311 self.tearDown()
312 except Exception:
313 result.addError(self, sys.exc_info())
314 success = False
316 cleanUpSuccess = self.doCleanups()
317 success = success and cleanUpSuccess
318 if success:
319 result.addSuccess(self)
320 finally:
321 result.stopTest(self)
322 if orig_result is None:
323 stopTestRun = getattr(result, 'stopTestRun', None)
324 if stopTestRun is not None:
325 stopTestRun()
327 def doCleanups(self):
328 """Execute all cleanup functions. Normally called for you after
329 tearDown."""
330 result = self._resultForDoCleanups
331 ok = True
332 while self._cleanups:
333 function, args, kwargs = self._cleanups.pop(-1)
334 try:
335 function(*args, **kwargs)
336 except Exception:
337 ok = False
338 result.addError(self, sys.exc_info())
339 return ok
341 def __call__(self, *args, **kwds):
342 return self.run(*args, **kwds)
344 def debug(self):
345 """Run the test without collecting errors in a TestResult"""
346 self.setUp()
347 getattr(self, self._testMethodName)()
348 self.tearDown()
350 def skipTest(self, reason):
351 """Skip this test."""
352 raise SkipTest(reason)
354 def fail(self, msg=None):
355 """Fail immediately, with the given message."""
356 raise self.failureException(msg)
358 def assertFalse(self, expr, msg=None):
359 "Fail the test if the expression is true."
360 if expr:
361 msg = self._formatMessage(msg, "%r is not False" % expr)
362 raise self.failureException(msg)
364 def assertTrue(self, expr, msg=None):
365 """Fail the test unless the expression is true."""
366 if not expr:
367 msg = self._formatMessage(msg, "%r is not True" % expr)
368 raise self.failureException(msg)
370 def _formatMessage(self, msg, standardMsg):
371 """Honour the longMessage attribute when generating failure messages.
372 If longMessage is False this means:
373 * Use only an explicit message if it is provided
374 * Otherwise use the standard message for the assert
376 If longMessage is True:
377 * Use the standard message
378 * If an explicit message is provided, plus ' : ' and the explicit message
380 if not self.longMessage:
381 return msg or standardMsg
382 if msg is None:
383 return standardMsg
384 return standardMsg + ' : ' + msg
387 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
388 """Fail unless an exception of class excClass is thrown
389 by callableObj when invoked with arguments args and keyword
390 arguments kwargs. If a different type of exception is
391 thrown, it will not be caught, and the test case will be
392 deemed to have suffered an error, exactly as for an
393 unexpected exception.
395 If called with callableObj omitted or None, will return a
396 context object used like this::
398 with self.assertRaises(some_error_class):
399 do_something()
401 context = _AssertRaisesContext(excClass, self)
402 if callableObj is None:
403 return context
404 with context:
405 callableObj(*args, **kwargs)
407 def _getAssertEqualityFunc(self, first, second):
408 """Get a detailed comparison function for the types of the two args.
410 Returns: A callable accepting (first, second, msg=None) that will
411 raise a failure exception if first != second with a useful human
412 readable error message for those types.
415 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
416 # and vice versa. I opted for the conservative approach in case
417 # subclasses are not intended to be compared in detail to their super
418 # class instances using a type equality func. This means testing
419 # subtypes won't automagically use the detailed comparison. Callers
420 # should use their type specific assertSpamEqual method to compare
421 # subclasses if the detailed comparison is desired and appropriate.
422 # See the discussion in http://bugs.python.org/issue2578.
424 if type(first) is type(second):
425 asserter = self._type_equality_funcs.get(type(first))
426 if asserter is not None:
427 return asserter.function
429 return self._baseAssertEqual
431 def _baseAssertEqual(self, first, second, msg=None):
432 """The default assertEqual implementation, not type specific."""
433 if not first == second:
434 standardMsg = '%r != %r' % (first, second)
435 msg = self._formatMessage(msg, standardMsg)
436 raise self.failureException(msg)
438 def assertEqual(self, first, second, msg=None):
439 """Fail if the two objects are unequal as determined by the '=='
440 operator.
442 assertion_func = self._getAssertEqualityFunc(first, second)
443 assertion_func(first, second, msg=msg)
445 def assertNotEqual(self, first, second, msg=None):
446 """Fail if the two objects are equal as determined by the '=='
447 operator.
449 if not first != second:
450 msg = self._formatMessage(msg, '%r == %r' % (first, second))
451 raise self.failureException(msg)
453 def assertAlmostEqual(self, first, second, places=7, msg=None):
454 """Fail if the two objects are unequal as determined by their
455 difference rounded to the given number of decimal places
456 (default 7) and comparing to zero.
458 Note that decimal places (from zero) are usually not the same
459 as significant digits (measured from the most signficant digit).
461 If the two objects compare equal then they will automatically
462 compare almost equal.
464 if first == second:
465 # shortcut for ite
466 return
467 if round(abs(second-first), places) != 0:
468 standardMsg = '%r != %r within %r places' % (first, second, places)
469 msg = self._formatMessage(msg, standardMsg)
470 raise self.failureException(msg)
472 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
473 """Fail if the two objects are equal as determined by their
474 difference rounded to the given number of decimal places
475 (default 7) and comparing to zero.
477 Note that decimal places (from zero) are usually not the same
478 as significant digits (measured from the most signficant digit).
480 Objects that are equal automatically fail.
482 if (first == second) or round(abs(second-first), places) == 0:
483 standardMsg = '%r == %r within %r places' % (first, second, places)
484 msg = self._formatMessage(msg, standardMsg)
485 raise self.failureException(msg)
487 # Synonyms for assertion methods
489 # The plurals are undocumented. Keep them that way to discourage use.
490 # Do not add more. Do not remove.
491 # Going through a deprecation cycle on these would annoy many people.
492 assertEquals = assertEqual
493 assertNotEquals = assertNotEqual
494 assertAlmostEquals = assertAlmostEqual
495 assertNotAlmostEquals = assertNotAlmostEqual
496 assert_ = assertTrue
498 # These fail* assertion method names are pending deprecation and will
499 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
500 def _deprecate(original_func):
501 def deprecated_func(*args, **kwargs):
502 warnings.warn(
503 'Please use {0} instead.'.format(original_func.__name__),
504 PendingDeprecationWarning, 2)
505 return original_func(*args, **kwargs)
506 return deprecated_func
508 failUnlessEqual = _deprecate(assertEqual)
509 failIfEqual = _deprecate(assertNotEqual)
510 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
511 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
512 failUnless = _deprecate(assertTrue)
513 failUnlessRaises = _deprecate(assertRaises)
514 failIf = _deprecate(assertFalse)
516 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
517 """An equality assertion for ordered sequences (like lists and tuples).
519 For the purposes of this function, a valid orderd sequence type is one
520 which can be indexed, has a length, and has an equality operator.
522 Args:
523 seq1: The first sequence to compare.
524 seq2: The second sequence to compare.
525 seq_type: The expected datatype of the sequences, or None if no
526 datatype should be enforced.
527 msg: Optional message to use on failure instead of a list of
528 differences.
530 if seq_type != None:
531 seq_type_name = seq_type.__name__
532 if not isinstance(seq1, seq_type):
533 raise self.failureException('First sequence is not a %s: %r'
534 % (seq_type_name, seq1))
535 if not isinstance(seq2, seq_type):
536 raise self.failureException('Second sequence is not a %s: %r'
537 % (seq_type_name, seq2))
538 else:
539 seq_type_name = "sequence"
541 differing = None
542 try:
543 len1 = len(seq1)
544 except (TypeError, NotImplementedError):
545 differing = 'First %s has no length. Non-sequence?' % (
546 seq_type_name)
548 if differing is None:
549 try:
550 len2 = len(seq2)
551 except (TypeError, NotImplementedError):
552 differing = 'Second %s has no length. Non-sequence?' % (
553 seq_type_name)
555 if differing is None:
556 if seq1 == seq2:
557 return
559 seq1_repr = repr(seq1)
560 seq2_repr = repr(seq2)
561 if len(seq1_repr) > 30:
562 seq1_repr = seq1_repr[:30] + '...'
563 if len(seq2_repr) > 30:
564 seq2_repr = seq2_repr[:30] + '...'
565 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
566 differing = '%ss differ: %s != %s\n' % elements
568 for i in xrange(min(len1, len2)):
569 try:
570 item1 = seq1[i]
571 except (TypeError, IndexError, NotImplementedError):
572 differing += ('\nUnable to index element %d of first %s\n' %
573 (i, seq_type_name))
574 break
576 try:
577 item2 = seq2[i]
578 except (TypeError, IndexError, NotImplementedError):
579 differing += ('\nUnable to index element %d of second %s\n' %
580 (i, seq_type_name))
581 break
583 if item1 != item2:
584 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
585 (i, item1, item2))
586 break
587 else:
588 if (len1 == len2 and seq_type is None and
589 type(seq1) != type(seq2)):
590 # The sequences are the same, but have differing types.
591 return
593 if len1 > len2:
594 differing += ('\nFirst %s contains %d additional '
595 'elements.\n' % (seq_type_name, len1 - len2))
596 try:
597 differing += ('First extra element %d:\n%s\n' %
598 (len2, seq1[len2]))
599 except (TypeError, IndexError, NotImplementedError):
600 differing += ('Unable to index element %d '
601 'of first %s\n' % (len2, seq_type_name))
602 elif len1 < len2:
603 differing += ('\nSecond %s contains %d additional '
604 'elements.\n' % (seq_type_name, len2 - len1))
605 try:
606 differing += ('First extra element %d:\n%s\n' %
607 (len1, seq2[len1]))
608 except (TypeError, IndexError, NotImplementedError):
609 differing += ('Unable to index element %d '
610 'of second %s\n' % (len1, seq_type_name))
611 standardMsg = differing + '\n' + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
612 pprint.pformat(seq2).splitlines()))
613 msg = self._formatMessage(msg, standardMsg)
614 self.fail(msg)
616 def assertListEqual(self, list1, list2, msg=None):
617 """A list-specific equality assertion.
619 Args:
620 list1: The first list to compare.
621 list2: The second list to compare.
622 msg: Optional message to use on failure instead of a list of
623 differences.
626 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
628 def assertTupleEqual(self, tuple1, tuple2, msg=None):
629 """A tuple-specific equality assertion.
631 Args:
632 tuple1: The first tuple to compare.
633 tuple2: The second tuple to compare.
634 msg: Optional message to use on failure instead of a list of
635 differences.
637 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
639 def assertSetEqual(self, set1, set2, msg=None):
640 """A set-specific equality assertion.
642 Args:
643 set1: The first set to compare.
644 set2: The second set to compare.
645 msg: Optional message to use on failure instead of a list of
646 differences.
648 For more general containership equality, assertSameElements will work
649 with things other than sets. This uses ducktyping to support
650 different types of sets, and is optimized for sets specifically
651 (parameters must support a difference method).
653 try:
654 difference1 = set1.difference(set2)
655 except TypeError, e:
656 self.fail('invalid type when attempting set difference: %s' % e)
657 except AttributeError, e:
658 self.fail('first argument does not support set difference: %s' % e)
660 try:
661 difference2 = set2.difference(set1)
662 except TypeError, e:
663 self.fail('invalid type when attempting set difference: %s' % e)
664 except AttributeError, e:
665 self.fail('second argument does not support set difference: %s' % e)
667 if not (difference1 or difference2):
668 return
670 lines = []
671 if difference1:
672 lines.append('Items in the first set but not the second:')
673 for item in difference1:
674 lines.append(repr(item))
675 if difference2:
676 lines.append('Items in the second set but not the first:')
677 for item in difference2:
678 lines.append(repr(item))
680 standardMsg = '\n'.join(lines)
681 self.fail(self._formatMessage(msg, standardMsg))
683 def assertIn(self, member, container, msg=None):
684 """Just like self.assertTrue(a in b), but with a nicer default message."""
685 if member not in container:
686 standardMsg = '%r not found in %r' % (member, container)
687 self.fail(self._formatMessage(msg, standardMsg))
689 def assertNotIn(self, member, container, msg=None):
690 """Just like self.assertTrue(a not in b), but with a nicer default message."""
691 if member in container:
692 standardMsg = '%r unexpectedly found in %r' % (member, container)
693 self.fail(self._formatMessage(msg, standardMsg))
695 def assertIs(self, expr1, expr2, msg=None):
696 """Just like self.assertTrue(a is b), but with a nicer default message."""
697 if expr1 is not expr2:
698 standardMsg = '%r is not %r' % (expr1, expr2)
699 self.fail(self._formatMessage(msg, standardMsg))
701 def assertIsNot(self, expr1, expr2, msg=None):
702 """Just like self.assertTrue(a is not b), but with a nicer default message."""
703 if expr1 is expr2:
704 standardMsg = 'unexpectedly identical: %r' % (expr1,)
705 self.fail(self._formatMessage(msg, standardMsg))
707 def assertDictEqual(self, d1, d2, msg=None):
708 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
709 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
711 if d1 != d2:
712 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
713 pprint.pformat(d1).splitlines(),
714 pprint.pformat(d2).splitlines())))
715 self.fail(self._formatMessage(msg, standardMsg))
717 def assertDictContainsSubset(self, expected, actual, msg=None):
718 """Checks whether actual is a superset of expected."""
719 missing = []
720 mismatched = []
721 for key, value in expected.iteritems():
722 if key not in actual:
723 missing.append(key)
724 elif value != actual[key]:
725 mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key]))
727 if not (missing or mismatched):
728 return
730 standardMsg = ''
731 if missing:
732 standardMsg = 'Missing: %r' % ','.join(missing)
733 if mismatched:
734 if standardMsg:
735 standardMsg += '; '
736 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
738 self.fail(self._formatMessage(msg, standardMsg))
740 def assertSameElements(self, expected_seq, actual_seq, msg=None):
741 """An unordered sequence specific comparison.
743 Raises with an error message listing which elements of expected_seq
744 are missing from actual_seq and vice versa if any.
746 try:
747 expected = set(expected_seq)
748 actual = set(actual_seq)
749 missing = list(expected.difference(actual))
750 unexpected = list(actual.difference(expected))
751 missing.sort()
752 unexpected.sort()
753 except TypeError:
754 # Fall back to slower list-compare if any of the objects are
755 # not hashable.
756 expected = list(expected_seq)
757 actual = list(actual_seq)
758 expected.sort()
759 actual.sort()
760 missing, unexpected = util.sorted_list_difference(expected, actual)
761 errors = []
762 if missing:
763 errors.append('Expected, but missing:\n %r' % missing)
764 if unexpected:
765 errors.append('Unexpected, but present:\n %r' % unexpected)
766 if errors:
767 standardMsg = '\n'.join(errors)
768 self.fail(self._formatMessage(msg, standardMsg))
770 def assertMultiLineEqual(self, first, second, msg=None):
771 """Assert that two multi-line strings are equal."""
772 self.assert_(isinstance(first, basestring), (
773 'First argument is not a string'))
774 self.assert_(isinstance(second, basestring), (
775 'Second argument is not a string'))
777 if first != second:
778 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True)))
779 self.fail(self._formatMessage(msg, standardMsg))
781 def assertLess(self, a, b, msg=None):
782 """Just like self.assertTrue(a < b), but with a nicer default message."""
783 if not a < b:
784 standardMsg = '%r not less than %r' % (a, b)
785 self.fail(self._formatMessage(msg, standardMsg))
787 def assertLessEqual(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 or equal to %r' % (a, b)
791 self.fail(self._formatMessage(msg, standardMsg))
793 def assertGreater(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 greater than %r' % (a, b)
797 self.fail(self._formatMessage(msg, standardMsg))
799 def assertGreaterEqual(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 or equal to %r' % (a, b)
803 self.fail(self._formatMessage(msg, standardMsg))
805 def assertIsNone(self, obj, msg=None):
806 """Same as self.assertTrue(obj is None), with a nicer default message."""
807 if obj is not None:
808 standardMsg = '%r is not None' % obj
809 self.fail(self._formatMessage(msg, standardMsg))
811 def assertIsNotNone(self, obj, msg=None):
812 """Included for symmetry with assertIsNone."""
813 if obj is None:
814 standardMsg = 'unexpectedly None'
815 self.fail(self._formatMessage(msg, standardMsg))
817 def assertRaisesRegexp(self, expected_exception, expected_regexp,
818 callable_obj=None, *args, **kwargs):
819 """Asserts that the message in a raised exception matches a regexp.
821 Args:
822 expected_exception: Exception class expected to be raised.
823 expected_regexp: Regexp (re pattern object or string) expected
824 to be found in error message.
825 callable_obj: Function to be called.
826 args: Extra args.
827 kwargs: Extra kwargs.
829 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
830 if callable_obj is None:
831 return context
832 with context:
833 callable_obj(*args, **kwargs)
835 def assertRegexpMatches(self, text, expected_regex, msg=None):
836 if isinstance(expected_regex, basestring):
837 expected_regex = re.compile(expected_regex)
838 if not expected_regex.search(text):
839 msg = msg or "Regexp didn't match"
840 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
841 raise self.failureException(msg)
844 class FunctionTestCase(TestCase):
845 """A test case that wraps a test function.
847 This is useful for slipping pre-existing test functions into the
848 unittest framework. Optionally, set-up and tidy-up functions can be
849 supplied. As with TestCase, the tidy-up ('tearDown') function will
850 always be called if the set-up ('setUp') function ran successfully.
853 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
854 super(FunctionTestCase, self).__init__()
855 self._setUpFunc = setUp
856 self._tearDownFunc = tearDown
857 self._testFunc = testFunc
858 self._description = description
860 def setUp(self):
861 if self._setUpFunc is not None:
862 self._setUpFunc()
864 def tearDown(self):
865 if self._tearDownFunc is not None:
866 self._tearDownFunc()
868 def runTest(self):
869 self._testFunc()
871 def id(self):
872 return self._testFunc.__name__
874 def __eq__(self, other):
875 if not isinstance(other, self.__class__):
876 return NotImplemented
878 return self._setUpFunc == other._setUpFunc and \
879 self._tearDownFunc == other._tearDownFunc and \
880 self._testFunc == other._testFunc and \
881 self._description == other._description
883 def __ne__(self, other):
884 return not self == other
886 def __hash__(self):
887 return hash((type(self), self._setUpFunc, self._tearDownFunc,
888 self._testFunc, self._description))
890 def __str__(self):
891 return "%s (%s)" % (util.strclass(self.__class__),
892 self._testFunc.__name__)
894 def __repr__(self):
895 return "<%s testFunc=%s>" % (util.strclass(self.__class__),
896 self._testFunc)
898 def shortDescription(self):
899 if self._description is not None:
900 return self._description
901 doc = self._testFunc.__doc__
902 return doc and doc.split("\n")[0].strip() or None