Issue #7568: typo in docstring. Thanks Mike Putnam.
[python.git] / Lib / unittest / case.py
blob8da5743440e7d202842042345d1954fbbd8f6079
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 TestCase(object):
121 """A class whose instances are single test cases.
123 By default, the test code itself should be placed in a method named
124 'runTest'.
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.
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.
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.
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'
146 failureException = AssertionError
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.
152 longMessage = False
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.
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 = []
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)
180 def addTypeEqualityFunc(self, typeobj, function):
181 """Add a type specific assertEqual style function to compare a type.
183 This method is for use by TestCase subclasses that need to register
184 their own type equality functions to provide nicer error messages.
186 Args:
187 typeobj: The data type to call this function on when both values
188 are of the same type in assertEqual().
189 function: The callable taking two arguments and an optional
190 msg= argument that raises self.failureException with a
191 useful error message when the two arguments are not equal.
193 self._type_equality_funcs[typeobj] = function
195 def addCleanup(self, function, *args, **kwargs):
196 """Add a function, with arguments, to be called when the test is
197 completed. Functions added are called on a LIFO basis and are
198 called after tearDown on test failure or success.
200 Cleanup items are called even if setUp fails (unlike tearDown)."""
201 self._cleanups.append((function, args, kwargs))
203 def setUp(self):
204 "Hook method for setting up the test fixture before exercising it."
205 pass
207 def tearDown(self):
208 "Hook method for deconstructing the test fixture after testing it."
209 pass
211 def countTestCases(self):
212 return 1
214 def defaultTestResult(self):
215 return result.TestResult()
217 def shortDescription(self):
218 """Returns both the test method name and first line of its docstring.
220 If no docstring is given, only returns the method name.
222 This method overrides unittest.TestCase.shortDescription(), which
223 only returns the first line of the docstring, obscuring the name
224 of the test upon failure.
226 desc = str(self)
227 doc_first_line = None
229 if self._testMethodDoc:
230 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
231 if doc_first_line:
232 desc = '\n'.join((desc, doc_first_line))
233 return desc
235 def id(self):
236 return "%s.%s" % (util.strclass(self.__class__), self._testMethodName)
238 def __eq__(self, other):
239 if type(self) is not type(other):
240 return NotImplemented
242 return self._testMethodName == other._testMethodName
244 def __ne__(self, other):
245 return not self == other
247 def __hash__(self):
248 return hash((type(self), self._testMethodName))
250 def __str__(self):
251 return "%s (%s)" % (self._testMethodName, util.strclass(self.__class__))
253 def __repr__(self):
254 return "<%s testMethod=%s>" % \
255 (util.strclass(self.__class__), self._testMethodName)
257 def run(self, result=None):
258 orig_result = result
259 if result is None:
260 result = self.defaultTestResult()
261 startTestRun = getattr(result, 'startTestRun', None)
262 if startTestRun is not None:
263 startTestRun()
265 self._resultForDoCleanups = result
266 result.startTest(self)
267 if getattr(self.__class__, "__unittest_skip__", False):
268 # If the whole class was skipped.
269 try:
270 result.addSkip(self, self.__class__.__unittest_skip_why__)
271 finally:
272 result.stopTest(self)
273 return
274 testMethod = getattr(self, self._testMethodName)
275 try:
276 success = False
277 try:
278 self.setUp()
279 except SkipTest as e:
280 result.addSkip(self, str(e))
281 except Exception:
282 result.addError(self, sys.exc_info())
283 else:
284 try:
285 testMethod()
286 except self.failureException:
287 result.addFailure(self, sys.exc_info())
288 except _ExpectedFailure as e:
289 result.addExpectedFailure(self, e.exc_info)
290 except _UnexpectedSuccess:
291 result.addUnexpectedSuccess(self)
292 except SkipTest as e:
293 result.addSkip(self, str(e))
294 except Exception:
295 result.addError(self, sys.exc_info())
296 else:
297 success = True
299 try:
300 self.tearDown()
301 except Exception:
302 result.addError(self, sys.exc_info())
303 success = False
305 cleanUpSuccess = self.doCleanups()
306 success = success and cleanUpSuccess
307 if success:
308 result.addSuccess(self)
309 finally:
310 result.stopTest(self)
311 if orig_result is None:
312 stopTestRun = getattr(result, 'stopTestRun', None)
313 if stopTestRun is not None:
314 stopTestRun()
316 def doCleanups(self):
317 """Execute all cleanup functions. Normally called for you after
318 tearDown."""
319 result = self._resultForDoCleanups
320 ok = True
321 while self._cleanups:
322 function, args, kwargs = self._cleanups.pop(-1)
323 try:
324 function(*args, **kwargs)
325 except Exception:
326 ok = False
327 result.addError(self, sys.exc_info())
328 return ok
330 def __call__(self, *args, **kwds):
331 return self.run(*args, **kwds)
333 def debug(self):
334 """Run the test without collecting errors in a TestResult"""
335 self.setUp()
336 getattr(self, self._testMethodName)()
337 self.tearDown()
339 def skipTest(self, reason):
340 """Skip this test."""
341 raise SkipTest(reason)
343 def fail(self, msg=None):
344 """Fail immediately, with the given message."""
345 raise self.failureException(msg)
347 def assertFalse(self, expr, msg=None):
348 "Fail the test if the expression is true."
349 if expr:
350 msg = self._formatMessage(msg, "%r is not False" % expr)
351 raise self.failureException(msg)
353 def assertTrue(self, expr, msg=None):
354 """Fail the test unless the expression is true."""
355 if not expr:
356 msg = self._formatMessage(msg, "%r is not True" % expr)
357 raise self.failureException(msg)
359 def _formatMessage(self, msg, standardMsg):
360 """Honour the longMessage attribute when generating failure messages.
361 If longMessage is False this means:
362 * Use only an explicit message if it is provided
363 * Otherwise use the standard message for the assert
365 If longMessage is True:
366 * Use the standard message
367 * If an explicit message is provided, plus ' : ' and the explicit message
369 if not self.longMessage:
370 return msg or standardMsg
371 if msg is None:
372 return standardMsg
373 return standardMsg + ' : ' + msg
376 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
377 """Fail unless an exception of class excClass is thrown
378 by callableObj when invoked with arguments args and keyword
379 arguments kwargs. If a different type of exception is
380 thrown, it will not be caught, and the test case will be
381 deemed to have suffered an error, exactly as for an
382 unexpected exception.
384 If called with callableObj omitted or None, will return a
385 context object used like this::
387 with self.assertRaises(some_error_class):
388 do_something()
390 context = _AssertRaisesContext(excClass, self)
391 if callableObj is None:
392 return context
393 with context:
394 callableObj(*args, **kwargs)
396 def _getAssertEqualityFunc(self, first, second):
397 """Get a detailed comparison function for the types of the two args.
399 Returns: A callable accepting (first, second, msg=None) that will
400 raise a failure exception if first != second with a useful human
401 readable error message for those types.
404 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
405 # and vice versa. I opted for the conservative approach in case
406 # subclasses are not intended to be compared in detail to their super
407 # class instances using a type equality func. This means testing
408 # subtypes won't automagically use the detailed comparison. Callers
409 # should use their type specific assertSpamEqual method to compare
410 # subclasses if the detailed comparison is desired and appropriate.
411 # See the discussion in http://bugs.python.org/issue2578.
413 if type(first) is type(second):
414 asserter = self._type_equality_funcs.get(type(first))
415 if asserter is not None:
416 return asserter
418 return self._baseAssertEqual
420 def _baseAssertEqual(self, first, second, msg=None):
421 """The default assertEqual implementation, not type specific."""
422 if not first == second:
423 standardMsg = '%r != %r' % (first, second)
424 msg = self._formatMessage(msg, standardMsg)
425 raise self.failureException(msg)
427 def assertEqual(self, first, second, msg=None):
428 """Fail if the two objects are unequal as determined by the '=='
429 operator.
431 assertion_func = self._getAssertEqualityFunc(first, second)
432 assertion_func(first, second, msg=msg)
434 def assertNotEqual(self, first, second, msg=None):
435 """Fail if the two objects are equal as determined by the '=='
436 operator.
438 if not first != second:
439 msg = self._formatMessage(msg, '%r == %r' % (first, second))
440 raise self.failureException(msg)
442 def assertAlmostEqual(self, first, second, places=7, msg=None):
443 """Fail if the two objects are unequal as determined by their
444 difference rounded to the given number of decimal places
445 (default 7) and comparing to zero.
447 Note that decimal places (from zero) are usually not the same
448 as significant digits (measured from the most signficant digit).
450 If the two objects compare equal then they will automatically
451 compare almost equal.
453 if first == second:
454 # shortcut for ite
455 return
456 if round(abs(second-first), places) != 0:
457 standardMsg = '%r != %r within %r places' % (first, second, places)
458 msg = self._formatMessage(msg, standardMsg)
459 raise self.failureException(msg)
461 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
462 """Fail if the two objects are equal as determined by their
463 difference rounded to the given number of decimal places
464 (default 7) and comparing to zero.
466 Note that decimal places (from zero) are usually not the same
467 as significant digits (measured from the most signficant digit).
469 Objects that are equal automatically fail.
471 if (first == second) or round(abs(second-first), places) == 0:
472 standardMsg = '%r == %r within %r places' % (first, second, places)
473 msg = self._formatMessage(msg, standardMsg)
474 raise self.failureException(msg)
476 # Synonyms for assertion methods
478 # The plurals are undocumented. Keep them that way to discourage use.
479 # Do not add more. Do not remove.
480 # Going through a deprecation cycle on these would annoy many people.
481 assertEquals = assertEqual
482 assertNotEquals = assertNotEqual
483 assertAlmostEquals = assertAlmostEqual
484 assertNotAlmostEquals = assertNotAlmostEqual
485 assert_ = assertTrue
487 # These fail* assertion method names are pending deprecation and will
488 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
489 def _deprecate(original_func):
490 def deprecated_func(*args, **kwargs):
491 warnings.warn(
492 'Please use {0} instead.'.format(original_func.__name__),
493 PendingDeprecationWarning, 2)
494 return original_func(*args, **kwargs)
495 return deprecated_func
497 failUnlessEqual = _deprecate(assertEqual)
498 failIfEqual = _deprecate(assertNotEqual)
499 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
500 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
501 failUnless = _deprecate(assertTrue)
502 failUnlessRaises = _deprecate(assertRaises)
503 failIf = _deprecate(assertFalse)
505 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
506 """An equality assertion for ordered sequences (like lists and tuples).
508 For the purposes of this function, a valid orderd sequence type is one
509 which can be indexed, has a length, and has an equality operator.
511 Args:
512 seq1: The first sequence to compare.
513 seq2: The second sequence to compare.
514 seq_type: The expected datatype of the sequences, or None if no
515 datatype should be enforced.
516 msg: Optional message to use on failure instead of a list of
517 differences.
519 if seq_type != None:
520 seq_type_name = seq_type.__name__
521 if not isinstance(seq1, seq_type):
522 raise self.failureException('First sequence is not a %s: %r'
523 % (seq_type_name, seq1))
524 if not isinstance(seq2, seq_type):
525 raise self.failureException('Second sequence is not a %s: %r'
526 % (seq_type_name, seq2))
527 else:
528 seq_type_name = "sequence"
530 differing = None
531 try:
532 len1 = len(seq1)
533 except (TypeError, NotImplementedError):
534 differing = 'First %s has no length. Non-sequence?' % (
535 seq_type_name)
537 if differing is None:
538 try:
539 len2 = len(seq2)
540 except (TypeError, NotImplementedError):
541 differing = 'Second %s has no length. Non-sequence?' % (
542 seq_type_name)
544 if differing is None:
545 if seq1 == seq2:
546 return
548 seq1_repr = repr(seq1)
549 seq2_repr = repr(seq2)
550 if len(seq1_repr) > 30:
551 seq1_repr = seq1_repr[:30] + '...'
552 if len(seq2_repr) > 30:
553 seq2_repr = seq2_repr[:30] + '...'
554 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
555 differing = '%ss differ: %s != %s\n' % elements
557 for i in xrange(min(len1, len2)):
558 try:
559 item1 = seq1[i]
560 except (TypeError, IndexError, NotImplementedError):
561 differing += ('\nUnable to index element %d of first %s\n' %
562 (i, seq_type_name))
563 break
565 try:
566 item2 = seq2[i]
567 except (TypeError, IndexError, NotImplementedError):
568 differing += ('\nUnable to index element %d of second %s\n' %
569 (i, seq_type_name))
570 break
572 if item1 != item2:
573 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
574 (i, item1, item2))
575 break
576 else:
577 if (len1 == len2 and seq_type is None and
578 type(seq1) != type(seq2)):
579 # The sequences are the same, but have differing types.
580 return
582 if len1 > len2:
583 differing += ('\nFirst %s contains %d additional '
584 'elements.\n' % (seq_type_name, len1 - len2))
585 try:
586 differing += ('First extra element %d:\n%s\n' %
587 (len2, seq1[len2]))
588 except (TypeError, IndexError, NotImplementedError):
589 differing += ('Unable to index element %d '
590 'of first %s\n' % (len2, seq_type_name))
591 elif len1 < len2:
592 differing += ('\nSecond %s contains %d additional '
593 'elements.\n' % (seq_type_name, len2 - len1))
594 try:
595 differing += ('First extra element %d:\n%s\n' %
596 (len1, seq2[len1]))
597 except (TypeError, IndexError, NotImplementedError):
598 differing += ('Unable to index element %d '
599 'of second %s\n' % (len1, seq_type_name))
600 standardMsg = differing + '\n' + '\n'.join(
601 difflib.ndiff(pprint.pformat(seq1).splitlines(),
602 pprint.pformat(seq2).splitlines()))
603 msg = self._formatMessage(msg, standardMsg)
604 self.fail(msg)
606 def assertListEqual(self, list1, list2, msg=None):
607 """A list-specific equality assertion.
609 Args:
610 list1: The first list to compare.
611 list2: The second list to compare.
612 msg: Optional message to use on failure instead of a list of
613 differences.
616 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
618 def assertTupleEqual(self, tuple1, tuple2, msg=None):
619 """A tuple-specific equality assertion.
621 Args:
622 tuple1: The first tuple to compare.
623 tuple2: The second tuple to compare.
624 msg: Optional message to use on failure instead of a list of
625 differences.
627 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
629 def assertSetEqual(self, set1, set2, msg=None):
630 """A set-specific equality assertion.
632 Args:
633 set1: The first set to compare.
634 set2: The second set to compare.
635 msg: Optional message to use on failure instead of a list of
636 differences.
638 For more general containership equality, assertSameElements will work
639 with things other than sets. This uses ducktyping to support
640 different types of sets, and is optimized for sets specifically
641 (parameters must support a difference method).
643 try:
644 difference1 = set1.difference(set2)
645 except TypeError, e:
646 self.fail('invalid type when attempting set difference: %s' % e)
647 except AttributeError, e:
648 self.fail('first argument does not support set difference: %s' % e)
650 try:
651 difference2 = set2.difference(set1)
652 except TypeError, e:
653 self.fail('invalid type when attempting set difference: %s' % e)
654 except AttributeError, e:
655 self.fail('second argument does not support set difference: %s' % e)
657 if not (difference1 or difference2):
658 return
660 lines = []
661 if difference1:
662 lines.append('Items in the first set but not the second:')
663 for item in difference1:
664 lines.append(repr(item))
665 if difference2:
666 lines.append('Items in the second set but not the first:')
667 for item in difference2:
668 lines.append(repr(item))
670 standardMsg = '\n'.join(lines)
671 self.fail(self._formatMessage(msg, standardMsg))
673 def assertIn(self, member, container, msg=None):
674 """Just like self.assertTrue(a in b), but with a nicer default message."""
675 if member not in container:
676 standardMsg = '%r not found in %r' % (member, container)
677 self.fail(self._formatMessage(msg, standardMsg))
679 def assertNotIn(self, member, container, msg=None):
680 """Just like self.assertTrue(a not in b), but with a nicer default message."""
681 if member in container:
682 standardMsg = '%r unexpectedly found in %r' % (member, container)
683 self.fail(self._formatMessage(msg, standardMsg))
685 def assertIs(self, expr1, expr2, msg=None):
686 """Just like self.assertTrue(a is b), but with a nicer default message."""
687 if expr1 is not expr2:
688 standardMsg = '%r is not %r' % (expr1, expr2)
689 self.fail(self._formatMessage(msg, standardMsg))
691 def assertIsNot(self, expr1, expr2, msg=None):
692 """Just like self.assertTrue(a is not b), but with a nicer default message."""
693 if expr1 is expr2:
694 standardMsg = 'unexpectedly identical: %r' % (expr1,)
695 self.fail(self._formatMessage(msg, standardMsg))
697 def assertDictEqual(self, d1, d2, msg=None):
698 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
699 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
701 if d1 != d2:
702 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
703 pprint.pformat(d1).splitlines(),
704 pprint.pformat(d2).splitlines())))
705 self.fail(self._formatMessage(msg, standardMsg))
707 def assertDictContainsSubset(self, expected, actual, msg=None):
708 """Checks whether actual is a superset of expected."""
709 missing = []
710 mismatched = []
711 for key, value in expected.iteritems():
712 if key not in actual:
713 missing.append(key)
714 elif value != actual[key]:
715 mismatched.append('%s, expected: %s, actual: %s' %
716 (key, value, actual[key]))
718 if not (missing or mismatched):
719 return
721 standardMsg = ''
722 if missing:
723 standardMsg = 'Missing: %r' % ','.join(missing)
724 if mismatched:
725 if standardMsg:
726 standardMsg += '; '
727 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
729 self.fail(self._formatMessage(msg, standardMsg))
731 def assertSameElements(self, expected_seq, actual_seq, msg=None):
732 """An unordered sequence specific comparison.
734 Raises with an error message listing which elements of expected_seq
735 are missing from actual_seq and vice versa if any.
737 try:
738 expected = set(expected_seq)
739 actual = set(actual_seq)
740 missing = list(expected.difference(actual))
741 unexpected = list(actual.difference(expected))
742 missing.sort()
743 unexpected.sort()
744 except TypeError:
745 # Fall back to slower list-compare if any of the objects are
746 # not hashable.
747 expected = list(expected_seq)
748 actual = list(actual_seq)
749 expected.sort()
750 actual.sort()
751 missing, unexpected = util.sorted_list_difference(expected, actual)
752 errors = []
753 if missing:
754 errors.append('Expected, but missing:\n %r' % missing)
755 if unexpected:
756 errors.append('Unexpected, but present:\n %r' % unexpected)
757 if errors:
758 standardMsg = '\n'.join(errors)
759 self.fail(self._formatMessage(msg, standardMsg))
761 def assertMultiLineEqual(self, first, second, msg=None):
762 """Assert that two multi-line strings are equal."""
763 self.assert_(isinstance(first, basestring), (
764 'First argument is not a string'))
765 self.assert_(isinstance(second, basestring), (
766 'Second argument is not a string'))
768 if first != second:
769 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
770 second.splitlines(True)))
771 self.fail(self._formatMessage(msg, standardMsg))
773 def assertLess(self, a, b, msg=None):
774 """Just like self.assertTrue(a < b), but with a nicer default message."""
775 if not a < b:
776 standardMsg = '%r not less than %r' % (a, b)
777 self.fail(self._formatMessage(msg, standardMsg))
779 def assertLessEqual(self, a, b, msg=None):
780 """Just like self.assertTrue(a <= b), but with a nicer default message."""
781 if not a <= b:
782 standardMsg = '%r not less than or equal to %r' % (a, b)
783 self.fail(self._formatMessage(msg, standardMsg))
785 def assertGreater(self, a, b, msg=None):
786 """Just like self.assertTrue(a > b), but with a nicer default message."""
787 if not a > b:
788 standardMsg = '%r not greater than %r' % (a, b)
789 self.fail(self._formatMessage(msg, standardMsg))
791 def assertGreaterEqual(self, a, b, msg=None):
792 """Just like self.assertTrue(a >= b), but with a nicer default message."""
793 if not a >= b:
794 standardMsg = '%r not greater than or equal to %r' % (a, b)
795 self.fail(self._formatMessage(msg, standardMsg))
797 def assertIsNone(self, obj, msg=None):
798 """Same as self.assertTrue(obj is None), with a nicer default message."""
799 if obj is not None:
800 standardMsg = '%r is not None' % obj
801 self.fail(self._formatMessage(msg, standardMsg))
803 def assertIsNotNone(self, obj, msg=None):
804 """Included for symmetry with assertIsNone."""
805 if obj is None:
806 standardMsg = 'unexpectedly None'
807 self.fail(self._formatMessage(msg, standardMsg))
809 def assertIsInstance(self, obj, cls, msg=None):
810 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
811 default message."""
812 if not isinstance(obj, cls):
813 standardMsg = '%r is not an instance of %r' % (obj, cls)
814 self.fail(self._formatMessage(msg, standardMsg))
816 def assertNotIsInstance(self, obj, cls, msg=None):
817 """Included for symmetry with assertIsInstance."""
818 if isinstance(obj, cls):
819 standardMsg = '%r is an instance of %r' % (obj, cls)
820 self.fail(self._formatMessage(msg, standardMsg))
822 def assertRaisesRegexp(self, expected_exception, expected_regexp,
823 callable_obj=None, *args, **kwargs):
824 """Asserts that the message in a raised exception matches a regexp.
826 Args:
827 expected_exception: Exception class expected to be raised.
828 expected_regexp: Regexp (re pattern object or string) expected
829 to be found in error message.
830 callable_obj: Function to be called.
831 args: Extra args.
832 kwargs: Extra kwargs.
834 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
835 if callable_obj is None:
836 return context
837 with context:
838 callable_obj(*args, **kwargs)
840 def assertRegexpMatches(self, text, expected_regex, msg=None):
841 if isinstance(expected_regex, basestring):
842 expected_regex = re.compile(expected_regex)
843 if not expected_regex.search(text):
844 msg = msg or "Regexp didn't match"
845 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
846 raise self.failureException(msg)
849 class FunctionTestCase(TestCase):
850 """A test case that wraps a test function.
852 This is useful for slipping pre-existing test functions into the
853 unittest framework. Optionally, set-up and tidy-up functions can be
854 supplied. As with TestCase, the tidy-up ('tearDown') function will
855 always be called if the set-up ('setUp') function ran successfully.
858 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
859 super(FunctionTestCase, self).__init__()
860 self._setUpFunc = setUp
861 self._tearDownFunc = tearDown
862 self._testFunc = testFunc
863 self._description = description
865 def setUp(self):
866 if self._setUpFunc is not None:
867 self._setUpFunc()
869 def tearDown(self):
870 if self._tearDownFunc is not None:
871 self._tearDownFunc()
873 def runTest(self):
874 self._testFunc()
876 def id(self):
877 return self._testFunc.__name__
879 def __eq__(self, other):
880 if not isinstance(other, self.__class__):
881 return NotImplemented
883 return self._setUpFunc == other._setUpFunc and \
884 self._tearDownFunc == other._tearDownFunc and \
885 self._testFunc == other._testFunc and \
886 self._description == other._description
888 def __ne__(self, other):
889 return not self == other
891 def __hash__(self):
892 return hash((type(self), self._setUpFunc, self._tearDownFunc,
893 self._testFunc, self._description))
895 def __str__(self):
896 return "%s (%s)" % (util.strclass(self.__class__),
897 self._testFunc.__name__)
899 def __repr__(self):
900 return "<%s testFunc=%s>" % (util.strclass(self.__class__),
901 self._testFunc)
903 def shortDescription(self):
904 if self._description is not None:
905 return self._description
906 doc = self._testFunc.__doc__
907 return doc and doc.split("\n")[0].strip() or None