1 """Test case implementation"""
10 from . import result
, util
13 class SkipTest(Exception):
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.
22 class _ExpectedFailure(Exception):
24 Raise this when a test is expected to fail.
26 This is an implementation detail.
29 def __init__(self
, exc_info
):
30 super(_ExpectedFailure
, self
).__init
__()
31 self
.exc_info
= exc_info
33 class _UnexpectedSuccess(Exception):
35 The test was supposed to fail, but it didn't!
44 Unconditionally skip a test.
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
51 @functools.wraps(test_item
)
52 def skip_wrapper(*args
, **kwargs
):
53 raise SkipTest(reason
)
57 def skipIf(condition
, reason
):
59 Skip a test if the condition is true.
65 def skipUnless(condition
, reason
):
67 Skip a test unless the condition is true.
74 def expectedFailure(func
):
75 @functools.wraps(func
)
76 def wrapper(*args
, **kwargs
):
80 raise _ExpectedFailure(sys
.exc_info())
81 raise _UnexpectedSuccess
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
96 def __exit__(self
, exc_type
, exc_value
, tb
):
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
107 self
.exc_value
= exc_value
#store for later retrieval
108 if self
.expected_regex
is None:
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
)))
120 class _AssertWrapper(object):
121 """Wrap entries in the _type_equality_funcs registry to make them deep
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
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
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.
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
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
__
181 # Map types to custom assertEqual functions that will compare
182 # instances of said type in more detail to generate a more useful
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.
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
))
215 "Hook method for setting up the test fixture before exercising it."
219 "Hook method for deconstructing the test fixture after testing it."
222 def countTestCases(self
):
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.
238 doc_first_line
= None
240 if self
._testMethodDoc
:
241 doc_first_line
= self
._testMethodDoc
.split("\n")[0].strip()
243 desc
= '\n'.join((desc
, doc_first_line
))
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
259 return hash((type(self
), self
._testMethodName
))
262 return "%s (%s)" % (self
._testMethodName
, util
.strclass(self
.__class
__))
265 return "<%s testMethod=%s>" % \
266 (util
.strclass(self
.__class
__), self
._testMethodName
)
268 def run(self
, result
=None):
271 result
= self
.defaultTestResult()
272 startTestRun
= getattr(result
, 'startTestRun', None)
273 if startTestRun
is not None:
276 self
._resultForDoCleanups
= result
277 result
.startTest(self
)
278 if getattr(self
.__class
__, "__unittest_skip__", False):
279 # If the whole class was skipped.
281 result
.addSkip(self
, self
.__class
__.__unittest
_skip
_why
__)
283 result
.stopTest(self
)
285 testMethod
= getattr(self
, self
._testMethodName
)
290 except SkipTest
as e
:
291 result
.addSkip(self
, str(e
))
293 result
.addError(self
, sys
.exc_info())
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
))
306 result
.addError(self
, sys
.exc_info())
313 result
.addError(self
, sys
.exc_info())
316 cleanUpSuccess
= self
.doCleanups()
317 success
= success
and cleanUpSuccess
319 result
.addSuccess(self
)
321 result
.stopTest(self
)
322 if orig_result
is None:
323 stopTestRun
= getattr(result
, 'stopTestRun', None)
324 if stopTestRun
is not None:
327 def doCleanups(self
):
328 """Execute all cleanup functions. Normally called for you after
330 result
= self
._resultForDoCleanups
332 while self
._cleanups
:
333 function
, args
, kwargs
= self
._cleanups
.pop(-1)
335 function(*args
, **kwargs
)
338 result
.addError(self
, sys
.exc_info())
341 def __call__(self
, *args
, **kwds
):
342 return self
.run(*args
, **kwds
)
345 """Run the test without collecting errors in a TestResult"""
347 getattr(self
, self
._testMethodName
)()
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."
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."""
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
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):
401 context
= _AssertRaisesContext(excClass
, self
)
402 if callableObj
is None:
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 '=='
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 '=='
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.
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
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
):
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.
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
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
))
539 seq_type_name
= "sequence"
544 except (TypeError, NotImplementedError):
545 differing
= 'First %s has no length. Non-sequence?' % (
548 if differing
is None:
551 except (TypeError, NotImplementedError):
552 differing
= 'Second %s has no length. Non-sequence?' % (
555 if differing
is None:
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
)):
571 except (TypeError, IndexError, NotImplementedError):
572 differing
+= ('\nUnable to index element %d of first %s\n' %
578 except (TypeError, IndexError, NotImplementedError):
579 differing
+= ('\nUnable to index element %d of second %s\n' %
584 differing
+= ('\nFirst differing element %d:\n%s\n%s\n' %
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.
594 differing
+= ('\nFirst %s contains %d additional '
595 'elements.\n' % (seq_type_name
, len1
- len2
))
597 differing
+= ('First extra element %d:\n%s\n' %
599 except (TypeError, IndexError, NotImplementedError):
600 differing
+= ('Unable to index element %d '
601 'of first %s\n' % (len2
, seq_type_name
))
603 differing
+= ('\nSecond %s contains %d additional '
604 'elements.\n' % (seq_type_name
, len2
- len1
))
606 differing
+= ('First extra element %d:\n%s\n' %
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(
612 difflib
.ndiff(pprint
.pformat(seq1
).splitlines(),
613 pprint
.pformat(seq2
).splitlines()))
614 msg
= self
._formatMessage
(msg
, standardMsg
)
617 def assertListEqual(self
, list1
, list2
, msg
=None):
618 """A list-specific equality assertion.
621 list1: The first list to compare.
622 list2: The second list to compare.
623 msg: Optional message to use on failure instead of a list of
627 self
.assertSequenceEqual(list1
, list2
, msg
, seq_type
=list)
629 def assertTupleEqual(self
, tuple1
, tuple2
, msg
=None):
630 """A tuple-specific equality assertion.
633 tuple1: The first tuple to compare.
634 tuple2: The second tuple to compare.
635 msg: Optional message to use on failure instead of a list of
638 self
.assertSequenceEqual(tuple1
, tuple2
, msg
, seq_type
=tuple)
640 def assertSetEqual(self
, set1
, set2
, msg
=None):
641 """A set-specific equality assertion.
644 set1: The first set to compare.
645 set2: The second set to compare.
646 msg: Optional message to use on failure instead of a list of
649 For more general containership equality, assertSameElements will work
650 with things other than sets. This uses ducktyping to support
651 different types of sets, and is optimized for sets specifically
652 (parameters must support a difference method).
655 difference1
= set1
.difference(set2
)
657 self
.fail('invalid type when attempting set difference: %s' % e
)
658 except AttributeError, e
:
659 self
.fail('first argument does not support set difference: %s' % e
)
662 difference2
= set2
.difference(set1
)
664 self
.fail('invalid type when attempting set difference: %s' % e
)
665 except AttributeError, e
:
666 self
.fail('second argument does not support set difference: %s' % e
)
668 if not (difference1
or difference2
):
673 lines
.append('Items in the first set but not the second:')
674 for item
in difference1
:
675 lines
.append(repr(item
))
677 lines
.append('Items in the second set but not the first:')
678 for item
in difference2
:
679 lines
.append(repr(item
))
681 standardMsg
= '\n'.join(lines
)
682 self
.fail(self
._formatMessage
(msg
, standardMsg
))
684 def assertIn(self
, member
, container
, msg
=None):
685 """Just like self.assertTrue(a in b), but with a nicer default message."""
686 if member
not in container
:
687 standardMsg
= '%r not found in %r' % (member
, container
)
688 self
.fail(self
._formatMessage
(msg
, standardMsg
))
690 def assertNotIn(self
, member
, container
, msg
=None):
691 """Just like self.assertTrue(a not in b), but with a nicer default message."""
692 if member
in container
:
693 standardMsg
= '%r unexpectedly found in %r' % (member
, container
)
694 self
.fail(self
._formatMessage
(msg
, standardMsg
))
696 def assertIs(self
, expr1
, expr2
, msg
=None):
697 """Just like self.assertTrue(a is b), but with a nicer default message."""
698 if expr1
is not expr2
:
699 standardMsg
= '%r is not %r' % (expr1
, expr2
)
700 self
.fail(self
._formatMessage
(msg
, standardMsg
))
702 def assertIsNot(self
, expr1
, expr2
, msg
=None):
703 """Just like self.assertTrue(a is not b), but with a nicer default message."""
705 standardMsg
= 'unexpectedly identical: %r' % (expr1
,)
706 self
.fail(self
._formatMessage
(msg
, standardMsg
))
708 def assertDictEqual(self
, d1
, d2
, msg
=None):
709 self
.assert_(isinstance(d1
, dict), 'First argument is not a dictionary')
710 self
.assert_(isinstance(d2
, dict), 'Second argument is not a dictionary')
713 standardMsg
= ('\n' + '\n'.join(difflib
.ndiff(
714 pprint
.pformat(d1
).splitlines(),
715 pprint
.pformat(d2
).splitlines())))
716 self
.fail(self
._formatMessage
(msg
, standardMsg
))
718 def assertDictContainsSubset(self
, expected
, actual
, msg
=None):
719 """Checks whether actual is a superset of expected."""
722 for key
, value
in expected
.iteritems():
723 if key
not in actual
:
725 elif value
!= actual
[key
]:
726 mismatched
.append('%s, expected: %s, actual: %s' %
727 (key
, value
, actual
[key
]))
729 if not (missing
or mismatched
):
734 standardMsg
= 'Missing: %r' % ','.join(missing
)
738 standardMsg
+= 'Mismatched values: %s' % ','.join(mismatched
)
740 self
.fail(self
._formatMessage
(msg
, standardMsg
))
742 def assertSameElements(self
, expected_seq
, actual_seq
, msg
=None):
743 """An unordered sequence specific comparison.
745 Raises with an error message listing which elements of expected_seq
746 are missing from actual_seq and vice versa if any.
749 expected
= set(expected_seq
)
750 actual
= set(actual_seq
)
751 missing
= list(expected
.difference(actual
))
752 unexpected
= list(actual
.difference(expected
))
756 # Fall back to slower list-compare if any of the objects are
758 expected
= list(expected_seq
)
759 actual
= list(actual_seq
)
762 missing
, unexpected
= util
.sorted_list_difference(expected
, actual
)
765 errors
.append('Expected, but missing:\n %r' % missing
)
767 errors
.append('Unexpected, but present:\n %r' % unexpected
)
769 standardMsg
= '\n'.join(errors
)
770 self
.fail(self
._formatMessage
(msg
, standardMsg
))
772 def assertMultiLineEqual(self
, first
, second
, msg
=None):
773 """Assert that two multi-line strings are equal."""
774 self
.assert_(isinstance(first
, basestring
), (
775 'First argument is not a string'))
776 self
.assert_(isinstance(second
, basestring
), (
777 'Second argument is not a string'))
780 standardMsg
= '\n' + ''.join(difflib
.ndiff(first
.splitlines(True),
781 second
.splitlines(True)))
782 self
.fail(self
._formatMessage
(msg
, standardMsg
))
784 def assertLess(self
, a
, b
, msg
=None):
785 """Just like self.assertTrue(a < b), but with a nicer default message."""
787 standardMsg
= '%r not less than %r' % (a
, b
)
788 self
.fail(self
._formatMessage
(msg
, standardMsg
))
790 def assertLessEqual(self
, a
, b
, msg
=None):
791 """Just like self.assertTrue(a <= b), but with a nicer default message."""
793 standardMsg
= '%r not less than or equal to %r' % (a
, b
)
794 self
.fail(self
._formatMessage
(msg
, standardMsg
))
796 def assertGreater(self
, a
, b
, msg
=None):
797 """Just like self.assertTrue(a > b), but with a nicer default message."""
799 standardMsg
= '%r not greater than %r' % (a
, b
)
800 self
.fail(self
._formatMessage
(msg
, standardMsg
))
802 def assertGreaterEqual(self
, a
, b
, msg
=None):
803 """Just like self.assertTrue(a >= b), but with a nicer default message."""
805 standardMsg
= '%r not greater than or equal to %r' % (a
, b
)
806 self
.fail(self
._formatMessage
(msg
, standardMsg
))
808 def assertIsNone(self
, obj
, msg
=None):
809 """Same as self.assertTrue(obj is None), with a nicer default message."""
811 standardMsg
= '%r is not None' % obj
812 self
.fail(self
._formatMessage
(msg
, standardMsg
))
814 def assertIsNotNone(self
, obj
, msg
=None):
815 """Included for symmetry with assertIsNone."""
817 standardMsg
= 'unexpectedly None'
818 self
.fail(self
._formatMessage
(msg
, standardMsg
))
820 def assertIsInstance(self
, obj
, cls
, msg
=None):
821 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
823 if not isinstance(obj
, cls
):
824 standardMsg
= '%r is not an instance of %r' % (obj
, cls
)
825 self
.fail(self
._formatMessage
(msg
, standardMsg
))
827 def assertNotIsInstance(self
, obj
, cls
, msg
=None):
828 """Included for symmetry with assertIsInstance."""
829 if isinstance(obj
, cls
):
830 standardMsg
= '%r is an instance of %r' % (obj
, cls
)
831 self
.fail(self
._formatMessage
(msg
, standardMsg
))
833 def assertRaisesRegexp(self
, expected_exception
, expected_regexp
,
834 callable_obj
=None, *args
, **kwargs
):
835 """Asserts that the message in a raised exception matches a regexp.
838 expected_exception: Exception class expected to be raised.
839 expected_regexp: Regexp (re pattern object or string) expected
840 to be found in error message.
841 callable_obj: Function to be called.
843 kwargs: Extra kwargs.
845 context
= _AssertRaisesContext(expected_exception
, self
, expected_regexp
)
846 if callable_obj
is None:
849 callable_obj(*args
, **kwargs
)
851 def assertRegexpMatches(self
, text
, expected_regex
, msg
=None):
852 if isinstance(expected_regex
, basestring
):
853 expected_regex
= re
.compile(expected_regex
)
854 if not expected_regex
.search(text
):
855 msg
= msg
or "Regexp didn't match"
856 msg
= '%s: %r not found in %r' % (msg
, expected_regex
.pattern
, text
)
857 raise self
.failureException(msg
)
860 class FunctionTestCase(TestCase
):
861 """A test case that wraps a test function.
863 This is useful for slipping pre-existing test functions into the
864 unittest framework. Optionally, set-up and tidy-up functions can be
865 supplied. As with TestCase, the tidy-up ('tearDown') function will
866 always be called if the set-up ('setUp') function ran successfully.
869 def __init__(self
, testFunc
, setUp
=None, tearDown
=None, description
=None):
870 super(FunctionTestCase
, self
).__init
__()
871 self
._setUpFunc
= setUp
872 self
._tearDownFunc
= tearDown
873 self
._testFunc
= testFunc
874 self
._description
= description
877 if self
._setUpFunc
is not None:
881 if self
._tearDownFunc
is not None:
888 return self
._testFunc
.__name
__
890 def __eq__(self
, other
):
891 if not isinstance(other
, self
.__class
__):
892 return NotImplemented
894 return self
._setUpFunc
== other
._setUpFunc
and \
895 self
._tearDownFunc
== other
._tearDownFunc
and \
896 self
._testFunc
== other
._testFunc
and \
897 self
._description
== other
._description
899 def __ne__(self
, other
):
900 return not self
== other
903 return hash((type(self
), self
._setUpFunc
, self
._tearDownFunc
,
904 self
._testFunc
, self
._description
))
907 return "%s (%s)" % (util
.strclass(self
.__class
__),
908 self
._testFunc
.__name
__)
911 return "<%s testFunc=%s>" % (util
.strclass(self
.__class
__),
914 def shortDescription(self
):
915 if self
._description
is not None:
916 return self
._description
917 doc
= self
._testFunc
.__doc
__
918 return doc
and doc
.split("\n")[0].strip() or None