07278be0e4f6664fe7e21d890cc3b9bcf378577b
[metze/samba/wip.git] / lib / testtools / testtools / testcase.py
1 # Copyright (c) 2008-2011 testtools developers. See LICENSE for details.
2
3 """Test case related stuff."""
4
5 __metaclass__ = type
6 __all__ = [
7     'clone_test_with_new_id',
8     'ExpectedException',
9     'gather_details',
10     'run_test_with',
11     'skip',
12     'skipIf',
13     'skipUnless',
14     'TestCase',
15     ]
16
17 import copy
18 import itertools
19 import sys
20 import types
21 import unittest
22
23 from testtools import (
24     content,
25     try_import,
26     )
27 from testtools.compat import (
28     advance_iterator,
29     reraise,
30     )
31 from testtools.matchers import (
32     Annotate,
33     Contains,
34     Equals,
35     MatchesAll,
36     MatchesException,
37     MismatchError,
38     Is,
39     IsInstance,
40     Not,
41     Raises,
42     )
43 from testtools.monkey import patch
44 from testtools.runtest import RunTest
45 from testtools.testresult import TestResult
46
47 wraps = try_import('functools.wraps')
48
49 class TestSkipped(Exception):
50     """Raised within TestCase.run() when a test is skipped."""
51 testSkipped = try_import('unittest2.case.SkipTest', TestSkipped)
52 TestSkipped = try_import('unittest.case.SkipTest', TestSkipped)
53
54
55 class _UnexpectedSuccess(Exception):
56     """An unexpected success was raised.
57
58     Note that this exception is private plumbing in testtools' testcase
59     module.
60     """
61 _UnexpectedSuccess = try_import(
62     'unittest2.case._UnexpectedSuccess', _UnexpectedSuccess)
63 _UnexpectedSuccess = try_import(
64     'unittest.case._UnexpectedSuccess', _UnexpectedSuccess)
65
66 class _ExpectedFailure(Exception):
67     """An expected failure occured.
68
69     Note that this exception is private plumbing in testtools' testcase
70     module.
71     """
72 _ExpectedFailure = try_import(
73     'unittest2.case._ExpectedFailure', _ExpectedFailure)
74 _ExpectedFailure = try_import(
75     'unittest.case._ExpectedFailure', _ExpectedFailure)
76
77
78 def run_test_with(test_runner, **kwargs):
79     """Decorate a test as using a specific ``RunTest``.
80
81     e.g.::
82
83       @run_test_with(CustomRunner, timeout=42)
84       def test_foo(self):
85           self.assertTrue(True)
86
87     The returned decorator works by setting an attribute on the decorated
88     function.  `TestCase.__init__` looks for this attribute when deciding on a
89     ``RunTest`` factory.  If you wish to use multiple decorators on a test
90     method, then you must either make this one the top-most decorator, or you
91     must write your decorators so that they update the wrapping function with
92     the attributes of the wrapped function.  The latter is recommended style
93     anyway.  ``functools.wraps``, ``functools.wrapper`` and
94     ``twisted.python.util.mergeFunctionMetadata`` can help you do this.
95
96     :param test_runner: A ``RunTest`` factory that takes a test case and an
97         optional list of exception handlers.  See ``RunTest``.
98     :param kwargs: Keyword arguments to pass on as extra arguments to
99         'test_runner'.
100     :return: A decorator to be used for marking a test as needing a special
101         runner.
102     """
103     def decorator(function):
104         # Set an attribute on 'function' which will inform TestCase how to
105         # make the runner.
106         function._run_test_with = (
107             lambda case, handlers=None:
108                 test_runner(case, handlers=handlers, **kwargs))
109         return function
110     return decorator
111
112
113 def _copy_content(content_object):
114     """Make a copy of the given content object.
115
116     The content within ``content_object`` is iterated and saved. This is
117     useful when the source of the content is volatile, a log file in a
118     temporary directory for example.
119
120     :param content_object: A `content.Content` instance.
121     :return: A `content.Content` instance with the same mime-type as
122         ``content_object`` and a non-volatile copy of its content.
123     """
124     content_bytes = list(content_object.iter_bytes())
125     content_callback = lambda: content_bytes
126     return content.Content(content_object.content_type, content_callback)
127
128
129 def gather_details(source_dict, target_dict):
130     """Merge the details from ``source_dict`` into ``target_dict``.
131
132     :param source_dict: A dictionary of details will be gathered.
133     :param target_dict: A dictionary into which details will be gathered.
134     """
135     for name, content_object in source_dict.items():
136         new_name = name
137         disambiguator = itertools.count(1)
138         while new_name in target_dict:
139             new_name = '%s-%d' % (name, advance_iterator(disambiguator))
140         name = new_name
141         target_dict[name] = _copy_content(content_object)
142
143
144 class TestCase(unittest.TestCase):
145     """Extensions to the basic TestCase.
146
147     :ivar exception_handlers: Exceptions to catch from setUp, runTest and
148         tearDown. This list is able to be modified at any time and consists of
149         (exception_class, handler(case, result, exception_value)) pairs.
150     :cvar run_tests_with: A factory to make the ``RunTest`` to run tests with.
151         Defaults to ``RunTest``.  The factory is expected to take a test case
152         and an optional list of exception handlers.
153     """
154
155     skipException = TestSkipped
156
157     run_tests_with = RunTest
158
159     def __init__(self, *args, **kwargs):
160         """Construct a TestCase.
161
162         :param testMethod: The name of the method to run.
163         :keyword runTest: Optional class to use to execute the test. If not
164             supplied ``RunTest`` is used. The instance to be used is created
165             when run() is invoked, so will be fresh each time. Overrides
166             ``TestCase.run_tests_with`` if given.
167         """
168         runTest = kwargs.pop('runTest', None)
169         super(TestCase, self).__init__(*args, **kwargs)
170         self._cleanups = []
171         self._unique_id_gen = itertools.count(1)
172         # Generators to ensure unique traceback ids.  Maps traceback label to
173         # iterators.
174         self._traceback_id_gens = {}
175         self.__setup_called = False
176         self.__teardown_called = False
177         # __details is lazy-initialized so that a constructed-but-not-run
178         # TestCase is safe to use with clone_test_with_new_id.
179         self.__details = None
180         test_method = self._get_test_method()
181         if runTest is None:
182             runTest = getattr(
183                 test_method, '_run_test_with', self.run_tests_with)
184         self.__RunTest = runTest
185         self.__exception_handlers = []
186         self.exception_handlers = [
187             (self.skipException, self._report_skip),
188             (self.failureException, self._report_failure),
189             (_ExpectedFailure, self._report_expected_failure),
190             (_UnexpectedSuccess, self._report_unexpected_success),
191             (Exception, self._report_error),
192             ]
193         if sys.version_info < (2, 6):
194             # Catch old-style string exceptions with None as the instance
195             self.exception_handlers.append((type(None), self._report_error))
196
197     def __eq__(self, other):
198         eq = getattr(unittest.TestCase, '__eq__', None)
199         if eq is not None and not unittest.TestCase.__eq__(self, other):
200             return False
201         return self.__dict__ == other.__dict__
202
203     def __repr__(self):
204         # We add id to the repr because it makes testing testtools easier.
205         return "<%s id=0x%0x>" % (self.id(), id(self))
206
207     def addDetail(self, name, content_object):
208         """Add a detail to be reported with this test's outcome.
209
210         For more details see pydoc testtools.TestResult.
211
212         :param name: The name to give this detail.
213         :param content_object: The content object for this detail. See
214             testtools.content for more detail.
215         """
216         if self.__details is None:
217             self.__details = {}
218         self.__details[name] = content_object
219
220     def getDetails(self):
221         """Get the details dict that will be reported with this test's outcome.
222
223         For more details see pydoc testtools.TestResult.
224         """
225         if self.__details is None:
226             self.__details = {}
227         return self.__details
228
229     def patch(self, obj, attribute, value):
230         """Monkey-patch 'obj.attribute' to 'value' while the test is running.
231
232         If 'obj' has no attribute, then the monkey-patch will still go ahead,
233         and the attribute will be deleted instead of restored to its original
234         value.
235
236         :param obj: The object to patch. Can be anything.
237         :param attribute: The attribute on 'obj' to patch.
238         :param value: The value to set 'obj.attribute' to.
239         """
240         self.addCleanup(patch(obj, attribute, value))
241
242     def shortDescription(self):
243         return self.id()
244
245     def skipTest(self, reason):
246         """Cause this test to be skipped.
247
248         This raises self.skipException(reason). skipException is raised
249         to permit a skip to be triggered at any point (during setUp or the
250         testMethod itself). The run() method catches skipException and
251         translates that into a call to the result objects addSkip method.
252
253         :param reason: The reason why the test is being skipped. This must
254             support being cast into a unicode string for reporting.
255         """
256         raise self.skipException(reason)
257
258     # skipTest is how python2.7 spells this. Sometime in the future
259     # This should be given a deprecation decorator - RBC 20100611.
260     skip = skipTest
261
262     def _formatTypes(self, classOrIterable):
263         """Format a class or a bunch of classes for display in an error."""
264         className = getattr(classOrIterable, '__name__', None)
265         if className is None:
266             className = ', '.join(klass.__name__ for klass in classOrIterable)
267         return className
268
269     def addCleanup(self, function, *arguments, **keywordArguments):
270         """Add a cleanup function to be called after tearDown.
271
272         Functions added with addCleanup will be called in reverse order of
273         adding after tearDown, or after setUp if setUp raises an exception.
274
275         If a function added with addCleanup raises an exception, the error
276         will be recorded as a test error, and the next cleanup will then be
277         run.
278
279         Cleanup functions are always called before a test finishes running,
280         even if setUp is aborted by an exception.
281         """
282         self._cleanups.append((function, arguments, keywordArguments))
283
284     def addOnException(self, handler):
285         """Add a handler to be called when an exception occurs in test code.
286
287         This handler cannot affect what result methods are called, and is
288         called before any outcome is called on the result object. An example
289         use for it is to add some diagnostic state to the test details dict
290         which is expensive to calculate and not interesting for reporting in
291         the success case.
292
293         Handlers are called before the outcome (such as addFailure) that
294         the exception has caused.
295
296         Handlers are called in first-added, first-called order, and if they
297         raise an exception, that will propogate out of the test running
298         machinery, halting test processing. As a result, do not call code that
299         may unreasonably fail.
300         """
301         self.__exception_handlers.append(handler)
302
303     def _add_reason(self, reason):
304         self.addDetail('reason', content.Content(
305             content.ContentType('text', 'plain'),
306             lambda: [reason.encode('utf8')]))
307
308     def assertEqual(self, expected, observed, message=''):
309         """Assert that 'expected' is equal to 'observed'.
310
311         :param expected: The expected value.
312         :param observed: The observed value.
313         :param message: An optional message to include in the error.
314         """
315         matcher = Equals(expected)
316         self.assertThat(observed, matcher, message)
317
318     failUnlessEqual = assertEquals = assertEqual
319
320     def assertIn(self, needle, haystack):
321         """Assert that needle is in haystack."""
322         self.assertThat(haystack, Contains(needle))
323
324     def assertIsNone(self, observed, message=''):
325         """Assert that 'observed' is equal to None.
326
327         :param observed: The observed value.
328         :param message: An optional message describing the error.
329         """
330         matcher = Is(None)
331         self.assertThat(observed, matcher, message)
332
333     def assertIsNotNone(self, observed, message=''):
334         """Assert that 'observed' is not equal to None.
335
336         :param observed: The observed value.
337         :param message: An optional message describing the error.
338         """
339         matcher = Not(Is(None))
340         self.assertThat(observed, matcher, message)
341
342     def assertIs(self, expected, observed, message=''):
343         """Assert that 'expected' is 'observed'.
344
345         :param expected: The expected value.
346         :param observed: The observed value.
347         :param message: An optional message describing the error.
348         """
349         matcher = Is(expected)
350         self.assertThat(observed, matcher, message)
351
352     def assertIsNot(self, expected, observed, message=''):
353         """Assert that 'expected' is not 'observed'."""
354         matcher = Not(Is(expected))
355         self.assertThat(observed, matcher, message)
356
357     def assertNotIn(self, needle, haystack):
358         """Assert that needle is not in haystack."""
359         matcher = Not(Contains(needle))
360         self.assertThat(haystack, matcher)
361
362     def assertIsInstance(self, obj, klass, msg=None):
363         if isinstance(klass, tuple):
364             matcher = IsInstance(*klass)
365         else:
366             matcher = IsInstance(klass)
367         self.assertThat(obj, matcher, msg)
368
369     def assertRaises(self, excClass, callableObj, *args, **kwargs):
370         """Fail unless an exception of class excClass is thrown
371            by callableObj when invoked with arguments args and keyword
372            arguments kwargs. If a different type of exception is
373            thrown, it will not be caught, and the test case will be
374            deemed to have suffered an error, exactly as for an
375            unexpected exception.
376         """
377         class ReRaiseOtherTypes(object):
378             def match(self, matchee):
379                 if not issubclass(matchee[0], excClass):
380                     reraise(*matchee)
381         class CaptureMatchee(object):
382             def match(self, matchee):
383                 self.matchee = matchee[1]
384         capture = CaptureMatchee()
385         matcher = Raises(MatchesAll(ReRaiseOtherTypes(),
386                 MatchesException(excClass), capture))
387
388         self.assertThat(lambda: callableObj(*args, **kwargs), matcher)
389         return capture.matchee
390     failUnlessRaises = assertRaises
391
392     def assertThat(self, matchee, matcher, message='', verbose=False):
393         """Assert that matchee is matched by matcher.
394
395         :param matchee: An object to match with matcher.
396         :param matcher: An object meeting the testtools.Matcher protocol.
397         :raises MismatchError: When matcher does not match thing.
398         """
399         matcher = Annotate.if_message(message, matcher)
400         mismatch = matcher.match(matchee)
401         if not mismatch:
402             return
403         existing_details = self.getDetails()
404         for (name, content) in mismatch.get_details().items():
405             full_name = name
406             suffix = 1
407             while full_name in existing_details:
408                 full_name = "%s-%d" % (name, suffix)
409                 suffix += 1
410             self.addDetail(full_name, content)
411         raise MismatchError(matchee, matcher, mismatch, verbose)
412
413     def defaultTestResult(self):
414         return TestResult()
415
416     def expectFailure(self, reason, predicate, *args, **kwargs):
417         """Check that a test fails in a particular way.
418
419         If the test fails in the expected way, a KnownFailure is caused. If it
420         succeeds an UnexpectedSuccess is caused.
421
422         The expected use of expectFailure is as a barrier at the point in a
423         test where the test would fail. For example:
424         >>> def test_foo(self):
425         >>>    self.expectFailure("1 should be 0", self.assertNotEqual, 1, 0)
426         >>>    self.assertEqual(1, 0)
427
428         If in the future 1 were to equal 0, the expectFailure call can simply
429         be removed. This separation preserves the original intent of the test
430         while it is in the expectFailure mode.
431         """
432         # TODO: implement with matchers.
433         self._add_reason(reason)
434         try:
435             predicate(*args, **kwargs)
436         except self.failureException:
437             # GZ 2010-08-12: Don't know how to avoid exc_info cycle as the new
438             #                unittest _ExpectedFailure wants old traceback
439             exc_info = sys.exc_info()
440             try:
441                 self._report_traceback(exc_info)
442                 raise _ExpectedFailure(exc_info)
443             finally:
444                 del exc_info
445         else:
446             raise _UnexpectedSuccess(reason)
447
448     def getUniqueInteger(self):
449         """Get an integer unique to this test.
450
451         Returns an integer that is guaranteed to be unique to this instance.
452         Use this when you need an arbitrary integer in your test, or as a
453         helper for custom anonymous factory methods.
454         """
455         return advance_iterator(self._unique_id_gen)
456
457     def getUniqueString(self, prefix=None):
458         """Get a string unique to this test.
459
460         Returns a string that is guaranteed to be unique to this instance. Use
461         this when you need an arbitrary string in your test, or as a helper
462         for custom anonymous factory methods.
463
464         :param prefix: The prefix of the string. If not provided, defaults
465             to the id of the tests.
466         :return: A bytestring of '<prefix>-<unique_int>'.
467         """
468         if prefix is None:
469             prefix = self.id()
470         return '%s-%d' % (prefix, self.getUniqueInteger())
471
472     def onException(self, exc_info, tb_label='traceback'):
473         """Called when an exception propogates from test code.
474
475         :seealso addOnException:
476         """
477         if exc_info[0] not in [
478             TestSkipped, _UnexpectedSuccess, _ExpectedFailure]:
479             self._report_traceback(exc_info, tb_label=tb_label)
480         for handler in self.__exception_handlers:
481             handler(exc_info)
482
483     @staticmethod
484     def _report_error(self, result, err):
485         result.addError(self, details=self.getDetails())
486
487     @staticmethod
488     def _report_expected_failure(self, result, err):
489         result.addExpectedFailure(self, details=self.getDetails())
490
491     @staticmethod
492     def _report_failure(self, result, err):
493         result.addFailure(self, details=self.getDetails())
494
495     @staticmethod
496     def _report_skip(self, result, err):
497         if err.args:
498             reason = err.args[0]
499         else:
500             reason = "no reason given."
501         self._add_reason(reason)
502         result.addSkip(self, details=self.getDetails())
503
504     def _report_traceback(self, exc_info, tb_label='traceback'):
505         id_gen = self._traceback_id_gens.setdefault(
506             tb_label, itertools.count(0))
507         tb_id = advance_iterator(id_gen)
508         if tb_id:
509             tb_label = '%s-%d' % (tb_label, tb_id)
510         self.addDetail(tb_label, content.TracebackContent(exc_info, self))
511
512     @staticmethod
513     def _report_unexpected_success(self, result, err):
514         result.addUnexpectedSuccess(self, details=self.getDetails())
515
516     def run(self, result=None):
517         return self.__RunTest(self, self.exception_handlers).run(result)
518
519     def _run_setup(self, result):
520         """Run the setUp function for this test.
521
522         :param result: A testtools.TestResult to report activity to.
523         :raises ValueError: If the base class setUp is not called, a
524             ValueError is raised.
525         """
526         ret = self.setUp()
527         if not self.__setup_called:
528             raise ValueError(
529                 "TestCase.setUp was not called. Have you upcalled all the "
530                 "way up the hierarchy from your setUp? e.g. Call "
531                 "super(%s, self).setUp() from your setUp()."
532                 % self.__class__.__name__)
533         return ret
534
535     def _run_teardown(self, result):
536         """Run the tearDown function for this test.
537
538         :param result: A testtools.TestResult to report activity to.
539         :raises ValueError: If the base class tearDown is not called, a
540             ValueError is raised.
541         """
542         ret = self.tearDown()
543         if not self.__teardown_called:
544             raise ValueError(
545                 "TestCase.tearDown was not called. Have you upcalled all the "
546                 "way up the hierarchy from your tearDown? e.g. Call "
547                 "super(%s, self).tearDown() from your tearDown()."
548                 % self.__class__.__name__)
549         return ret
550
551     def _get_test_method(self):
552         absent_attr = object()
553         # Python 2.5+
554         method_name = getattr(self, '_testMethodName', absent_attr)
555         if method_name is absent_attr:
556             # Python 2.4
557             method_name = getattr(self, '_TestCase__testMethodName')
558         return getattr(self, method_name)
559
560     def _run_test_method(self, result):
561         """Run the test method for this test.
562
563         :param result: A testtools.TestResult to report activity to.
564         :return: None.
565         """
566         return self._get_test_method()()
567
568     def useFixture(self, fixture):
569         """Use fixture in a test case.
570
571         The fixture will be setUp, and self.addCleanup(fixture.cleanUp) called.
572
573         :param fixture: The fixture to use.
574         :return: The fixture, after setting it up and scheduling a cleanup for
575            it.
576         """
577         try:
578             fixture.setUp()
579         except:
580             gather_details(fixture.getDetails(), self.getDetails())
581             raise
582         else:
583             self.addCleanup(fixture.cleanUp)
584             self.addCleanup(
585                 gather_details, fixture.getDetails(), self.getDetails())
586             return fixture
587
588     def setUp(self):
589         super(TestCase, self).setUp()
590         self.__setup_called = True
591
592     def tearDown(self):
593         super(TestCase, self).tearDown()
594         unittest.TestCase.tearDown(self)
595         self.__teardown_called = True
596
597
598 class PlaceHolder(object):
599     """A placeholder test.
600
601     `PlaceHolder` implements much of the same interface as TestCase and is
602     particularly suitable for being added to TestResults.
603     """
604
605     def __init__(self, test_id, short_description=None):
606         """Construct a `PlaceHolder`.
607
608         :param test_id: The id of the placeholder test.
609         :param short_description: The short description of the place holder
610             test. If not provided, the id will be used instead.
611         """
612         self._test_id = test_id
613         self._short_description = short_description
614
615     def __call__(self, result=None):
616         return self.run(result=result)
617
618     def __repr__(self):
619         internal = [self._test_id]
620         if self._short_description is not None:
621             internal.append(self._short_description)
622         return "<%s.%s(%s)>" % (
623             self.__class__.__module__,
624             self.__class__.__name__,
625             ", ".join(map(repr, internal)))
626
627     def __str__(self):
628         return self.id()
629
630     def countTestCases(self):
631         return 1
632
633     def debug(self):
634         pass
635
636     def id(self):
637         return self._test_id
638
639     def run(self, result=None):
640         if result is None:
641             result = TestResult()
642         result.startTest(self)
643         result.addSuccess(self)
644         result.stopTest(self)
645
646     def shortDescription(self):
647         if self._short_description is None:
648             return self.id()
649         else:
650             return self._short_description
651
652
653 class ErrorHolder(PlaceHolder):
654     """A placeholder test that will error out when run."""
655
656     failureException = None
657
658     def __init__(self, test_id, error, short_description=None):
659         """Construct an `ErrorHolder`.
660
661         :param test_id: The id of the test.
662         :param error: The exc info tuple that will be used as the test's error.
663         :param short_description: An optional short description of the test.
664         """
665         super(ErrorHolder, self).__init__(
666             test_id, short_description=short_description)
667         self._error = error
668
669     def __repr__(self):
670         internal = [self._test_id, self._error]
671         if self._short_description is not None:
672             internal.append(self._short_description)
673         return "<%s.%s(%s)>" % (
674             self.__class__.__module__,
675             self.__class__.__name__,
676             ", ".join(map(repr, internal)))
677
678     def run(self, result=None):
679         if result is None:
680             result = TestResult()
681         result.startTest(self)
682         result.addError(self, self._error)
683         result.stopTest(self)
684
685
686 # Python 2.4 did not know how to copy functions.
687 if types.FunctionType not in copy._copy_dispatch:
688     copy._copy_dispatch[types.FunctionType] = copy._copy_immutable
689
690
691 def clone_test_with_new_id(test, new_id):
692     """Copy a `TestCase`, and give the copied test a new id.
693
694     This is only expected to be used on tests that have been constructed but
695     not executed.
696     """
697     newTest = copy.copy(test)
698     newTest.id = lambda: new_id
699     return newTest
700
701
702 def skip(reason):
703     """A decorator to skip unit tests.
704
705     This is just syntactic sugar so users don't have to change any of their
706     unit tests in order to migrate to python 2.7, which provides the
707     @unittest.skip decorator.
708     """
709     def decorator(test_item):
710         if wraps is not None:
711             @wraps(test_item)
712             def skip_wrapper(*args, **kwargs):
713                 raise TestCase.skipException(reason)
714         else:
715             def skip_wrapper(test_item):
716                 test_item.skip(reason)
717         return skip_wrapper
718     return decorator
719
720
721 def skipIf(condition, reason):
722     """Skip a test if the condition is true."""
723     if condition:
724         return skip(reason)
725     def _id(obj):
726         return obj
727     return _id
728
729
730 def skipUnless(condition, reason):
731     """Skip a test unless the condition is true."""
732     if not condition:
733         return skip(reason)
734     def _id(obj):
735         return obj
736     return _id
737
738
739 class ExpectedException:
740     """A context manager to handle expected exceptions.
741
742     In Python 2.5 or later::
743
744       def test_foo(self):
745           with ExpectedException(ValueError, 'fo.*'):
746               raise ValueError('foo')
747
748     will pass.  If the raised exception has a type other than the specified
749     type, it will be re-raised.  If it has a 'str()' that does not match the
750     given regular expression, an AssertionError will be raised.  If no
751     exception is raised, an AssertionError will be raised.
752     """
753
754     def __init__(self, exc_type, value_re=None):
755         """Construct an `ExpectedException`.
756
757         :param exc_type: The type of exception to expect.
758         :param value_re: A regular expression to match against the
759             'str()' of the raised exception.
760         """
761         self.exc_type = exc_type
762         self.value_re = value_re
763
764     def __enter__(self):
765         pass
766
767     def __exit__(self, exc_type, exc_value, traceback):
768         if exc_type is None:
769             raise AssertionError('%s not raised.' % self.exc_type.__name__)
770         if exc_type != self.exc_type:
771             return False
772         if self.value_re:
773             matcher = MatchesException(self.exc_type, self.value_re)
774             mismatch = matcher.match((exc_type, exc_value, traceback))
775             if mismatch:
776                 raise AssertionError(mismatch.describe())
777         return True
778
779
780 # Signal that this is part of the testing framework, and that code from this
781 # should not normally appear in tracebacks.
782 __unittest = True