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(difflib
.ndiff(pprint
.pformat(seq1
).splitlines(),
612 pprint
.pformat(seq2
).splitlines()))
613 msg
= self
._formatMessage
(msg
, standardMsg
)
616 def assertListEqual(self
, list1
, list2
, msg
=None):
617 """A list-specific equality assertion.
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
626 self
.assertSequenceEqual(list1
, list2
, msg
, seq_type
=list)
628 def assertTupleEqual(self
, tuple1
, tuple2
, msg
=None):
629 """A tuple-specific equality assertion.
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
637 self
.assertSequenceEqual(tuple1
, tuple2
, msg
, seq_type
=tuple)
639 def assertSetEqual(self
, set1
, set2
, msg
=None):
640 """A set-specific equality assertion.
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
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).
654 difference1
= set1
.difference(set2
)
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
)
661 difference2
= set2
.difference(set1
)
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
):
672 lines
.append('Items in the first set but not the second:')
673 for item
in difference1
:
674 lines
.append(repr(item
))
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."""
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')
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."""
721 for key
, value
in expected
.iteritems():
722 if key
not in actual
:
724 elif value
!= actual
[key
]:
725 mismatched
.append('%s, expected: %s, actual: %s' % (key
, value
, actual
[key
]))
727 if not (missing
or mismatched
):
732 standardMsg
= 'Missing: %r' % ','.join(missing
)
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.
747 expected
= set(expected_seq
)
748 actual
= set(actual_seq
)
749 missing
= list(expected
.difference(actual
))
750 unexpected
= list(actual
.difference(expected
))
754 # Fall back to slower list-compare if any of the objects are
756 expected
= list(expected_seq
)
757 actual
= list(actual_seq
)
760 missing
, unexpected
= util
.sorted_list_difference(expected
, actual
)
763 errors
.append('Expected, but missing:\n %r' % missing
)
765 errors
.append('Unexpected, but present:\n %r' % unexpected
)
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'))
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."""
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."""
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."""
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."""
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."""
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."""
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.
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.
827 kwargs: Extra kwargs.
829 context
= _AssertRaisesContext(expected_exception
, self
, expected_regexp
)
830 if callable_obj
is None:
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
861 if self
._setUpFunc
is not None:
865 if self
._tearDownFunc
is not None:
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
887 return hash((type(self
), self
._setUpFunc
, self
._tearDownFunc
,
888 self
._testFunc
, self
._description
))
891 return "%s (%s)" % (util
.strclass(self
.__class
__),
892 self
._testFunc
.__name
__)
895 return "<%s testFunc=%s>" % (util
.strclass(self
.__class
__),
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