1"""Test case implementation"""
2
3import sys
4import functools
5import difflib
6import pprint
7import re
8import warnings
9import collections
10import contextlib
11import traceback
12import types
13
14from . import result
15from .util import (strclass, safe_repr, _count_diff_all_purpose,
16                   _count_diff_hashable, _common_shorten_repr)
17
18__unittest = True
19
20_subtest_msg_sentinel = object()
21
22DIFF_OMITTED = ('\nDiff is %s characters long. '
23                 'Set self.maxDiff to None to see it.')
24
25class SkipTest(Exception):
26    """
27    Raise this exception in a test to skip it.
28
29    Usually you can use TestCase.skipTest() or one of the skipping decorators
30    instead of raising this directly.
31    """
32
33class _ShouldStop(Exception):
34    """
35    The test should stop.
36    """
37
38class _UnexpectedSuccess(Exception):
39    """
40    The test was supposed to fail, but it didn't!
41    """
42
43
44class _Outcome(object):
45    def __init__(self, result=None):
46        self.expecting_failure = False
47        self.result = result
48        self.result_supports_subtests = hasattr(result, "addSubTest")
49        self.success = True
50        self.skipped = []
51        self.expectedFailure = None
52        self.errors = []
53
54    @contextlib.contextmanager
55    def testPartExecutor(self, test_case, isTest=False):
56        old_success = self.success
57        self.success = True
58        try:
59            yield
60        except KeyboardInterrupt:
61            raise
62        except SkipTest as e:
63            self.success = False
64            self.skipped.append((test_case, str(e)))
65        except _ShouldStop:
66            pass
67        except:
68            exc_info = sys.exc_info()
69            if self.expecting_failure:
70                self.expectedFailure = exc_info
71            else:
72                self.success = False
73                self.errors.append((test_case, exc_info))
74            # explicitly break a reference cycle:
75            # exc_info -> frame -> exc_info
76            exc_info = None
77        else:
78            if self.result_supports_subtests and self.success:
79                self.errors.append((test_case, None))
80        finally:
81            self.success = self.success and old_success
82
83
84def _id(obj):
85    return obj
86
87
88_module_cleanups = []
89def addModuleCleanup(function, /, *args, **kwargs):
90    """Same as addCleanup, except the cleanup items are called even if
91    setUpModule fails (unlike tearDownModule)."""
92    _module_cleanups.append((function, args, kwargs))
93
94
95def doModuleCleanups():
96    """Execute all module cleanup functions. Normally called for you after
97    tearDownModule."""
98    exceptions = []
99    while _module_cleanups:
100        function, args, kwargs = _module_cleanups.pop()
101        try:
102            function(*args, **kwargs)
103        except Exception as exc:
104            exceptions.append(exc)
105    if exceptions:
106        # Swallows all but first exception. If a multi-exception handler
107        # gets written we should use that here instead.
108        raise exceptions[0]
109
110
111def skip(reason):
112    """
113    Unconditionally skip a test.
114    """
115    def decorator(test_item):
116        if not isinstance(test_item, type):
117            @functools.wraps(test_item)
118            def skip_wrapper(*args, **kwargs):
119                raise SkipTest(reason)
120            test_item = skip_wrapper
121
122        test_item.__unittest_skip__ = True
123        test_item.__unittest_skip_why__ = reason
124        return test_item
125    if isinstance(reason, types.FunctionType):
126        test_item = reason
127        reason = ''
128        return decorator(test_item)
129    return decorator
130
131def skipIf(condition, reason):
132    """
133    Skip a test if the condition is true.
134    """
135    if condition:
136        return skip(reason)
137    return _id
138
139def skipUnless(condition, reason):
140    """
141    Skip a test unless the condition is true.
142    """
143    if not condition:
144        return skip(reason)
145    return _id
146
147def expectedFailure(test_item):
148    test_item.__unittest_expecting_failure__ = True
149    return test_item
150
151def _is_subtype(expected, basetype):
152    if isinstance(expected, tuple):
153        return all(_is_subtype(e, basetype) for e in expected)
154    return isinstance(expected, type) and issubclass(expected, basetype)
155
156class _BaseTestCaseContext:
157
158    def __init__(self, test_case):
159        self.test_case = test_case
160
161    def _raiseFailure(self, standardMsg):
162        msg = self.test_case._formatMessage(self.msg, standardMsg)
163        raise self.test_case.failureException(msg)
164
165class _AssertRaisesBaseContext(_BaseTestCaseContext):
166
167    def __init__(self, expected, test_case, expected_regex=None):
168        _BaseTestCaseContext.__init__(self, test_case)
169        self.expected = expected
170        self.test_case = test_case
171        if expected_regex is not None:
172            expected_regex = re.compile(expected_regex)
173        self.expected_regex = expected_regex
174        self.obj_name = None
175        self.msg = None
176
177    def handle(self, name, args, kwargs):
178        """
179        If args is empty, assertRaises/Warns is being used as a
180        context manager, so check for a 'msg' kwarg and return self.
181        If args is not empty, call a callable passing positional and keyword
182        arguments.
183        """
184        try:
185            if not _is_subtype(self.expected, self._base_type):
186                raise TypeError('%s() arg 1 must be %s' %
187                                (name, self._base_type_str))
188            if not args:
189                self.msg = kwargs.pop('msg', None)
190                if kwargs:
191                    raise TypeError('%r is an invalid keyword argument for '
192                                    'this function' % (next(iter(kwargs)),))
193                return self
194
195            callable_obj, *args = args
196            try:
197                self.obj_name = callable_obj.__name__
198            except AttributeError:
199                self.obj_name = str(callable_obj)
200            with self:
201                callable_obj(*args, **kwargs)
202        finally:
203            # bpo-23890: manually break a reference cycle
204            self = None
205
206
207class _AssertRaisesContext(_AssertRaisesBaseContext):
208    """A context manager used to implement TestCase.assertRaises* methods."""
209
210    _base_type = BaseException
211    _base_type_str = 'an exception type or tuple of exception types'
212
213    def __enter__(self):
214        return self
215
216    def __exit__(self, exc_type, exc_value, tb):
217        if exc_type is None:
218            try:
219                exc_name = self.expected.__name__
220            except AttributeError:
221                exc_name = str(self.expected)
222            if self.obj_name:
223                self._raiseFailure("{} not raised by {}".format(exc_name,
224                                                                self.obj_name))
225            else:
226                self._raiseFailure("{} not raised".format(exc_name))
227        else:
228            traceback.clear_frames(tb)
229        if not issubclass(exc_type, self.expected):
230            # let unexpected exceptions pass through
231            return False
232        # store exception, without traceback, for later retrieval
233        self.exception = exc_value.with_traceback(None)
234        if self.expected_regex is None:
235            return True
236
237        expected_regex = self.expected_regex
238        if not expected_regex.search(str(exc_value)):
239            self._raiseFailure('"{}" does not match "{}"'.format(
240                     expected_regex.pattern, str(exc_value)))
241        return True
242
243    __class_getitem__ = classmethod(types.GenericAlias)
244
245
246class _AssertWarnsContext(_AssertRaisesBaseContext):
247    """A context manager used to implement TestCase.assertWarns* methods."""
248
249    _base_type = Warning
250    _base_type_str = 'a warning type or tuple of warning types'
251
252    def __enter__(self):
253        # The __warningregistry__'s need to be in a pristine state for tests
254        # to work properly.
255        for v in sys.modules.values():
256            if getattr(v, '__warningregistry__', None):
257                v.__warningregistry__ = {}
258        self.warnings_manager = warnings.catch_warnings(record=True)
259        self.warnings = self.warnings_manager.__enter__()
260        warnings.simplefilter("always", self.expected)
261        return self
262
263    def __exit__(self, exc_type, exc_value, tb):
264        self.warnings_manager.__exit__(exc_type, exc_value, tb)
265        if exc_type is not None:
266            # let unexpected exceptions pass through
267            return
268        try:
269            exc_name = self.expected.__name__
270        except AttributeError:
271            exc_name = str(self.expected)
272        first_matching = None
273        for m in self.warnings:
274            w = m.message
275            if not isinstance(w, self.expected):
276                continue
277            if first_matching is None:
278                first_matching = w
279            if (self.expected_regex is not None and
280                not self.expected_regex.search(str(w))):
281                continue
282            # store warning for later retrieval
283            self.warning = w
284            self.filename = m.filename
285            self.lineno = m.lineno
286            return
287        # Now we simply try to choose a helpful failure message
288        if first_matching is not None:
289            self._raiseFailure('"{}" does not match "{}"'.format(
290                     self.expected_regex.pattern, str(first_matching)))
291        if self.obj_name:
292            self._raiseFailure("{} not triggered by {}".format(exc_name,
293                                                               self.obj_name))
294        else:
295            self._raiseFailure("{} not triggered".format(exc_name))
296
297
298
299class _OrderedChainMap(collections.ChainMap):
300    def __iter__(self):
301        seen = set()
302        for mapping in self.maps:
303            for k in mapping:
304                if k not in seen:
305                    seen.add(k)
306                    yield k
307
308
309class TestCase(object):
310    """A class whose instances are single test cases.
311
312    By default, the test code itself should be placed in a method named
313    'runTest'.
314
315    If the fixture may be used for many test cases, create as
316    many test methods as are needed. When instantiating such a TestCase
317    subclass, specify in the constructor arguments the name of the test method
318    that the instance is to execute.
319
320    Test authors should subclass TestCase for their own tests. Construction
321    and deconstruction of the test's environment ('fixture') can be
322    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
323
324    If it is necessary to override the __init__ method, the base class
325    __init__ method must always be called. It is important that subclasses
326    should not change the signature of their __init__ method, since instances
327    of the classes are instantiated automatically by parts of the framework
328    in order to be run.
329
330    When subclassing TestCase, you can set these attributes:
331    * failureException: determines which exception will be raised when
332        the instance's assertion methods fail; test methods raising this
333        exception will be deemed to have 'failed' rather than 'errored'.
334    * longMessage: determines whether long messages (including repr of
335        objects used in assert methods) will be printed on failure in *addition*
336        to any explicit message passed.
337    * maxDiff: sets the maximum length of a diff in failure messages
338        by assert methods using difflib. It is looked up as an instance
339        attribute so can be configured by individual tests if required.
340    """
341
342    failureException = AssertionError
343
344    longMessage = True
345
346    maxDiff = 80*8
347
348    # If a string is longer than _diffThreshold, use normal comparison instead
349    # of difflib.  See #11763.
350    _diffThreshold = 2**16
351
352    # Attribute used by TestSuite for classSetUp
353
354    _classSetupFailed = False
355
356    _class_cleanups = []
357
358    def __init__(self, methodName='runTest'):
359        """Create an instance of the class that will use the named test
360           method when executed. Raises a ValueError if the instance does
361           not have a method with the specified name.
362        """
363        self._testMethodName = methodName
364        self._outcome = None
365        self._testMethodDoc = 'No test'
366        try:
367            testMethod = getattr(self, methodName)
368        except AttributeError:
369            if methodName != 'runTest':
370                # we allow instantiation with no explicit method name
371                # but not an *incorrect* or missing method name
372                raise ValueError("no such test method in %s: %s" %
373                      (self.__class__, methodName))
374        else:
375            self._testMethodDoc = testMethod.__doc__
376        self._cleanups = []
377        self._subtest = None
378
379        # Map types to custom assertEqual functions that will compare
380        # instances of said type in more detail to generate a more useful
381        # error message.
382        self._type_equality_funcs = {}
383        self.addTypeEqualityFunc(dict, 'assertDictEqual')
384        self.addTypeEqualityFunc(list, 'assertListEqual')
385        self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
386        self.addTypeEqualityFunc(set, 'assertSetEqual')
387        self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
388        self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
389
390    def addTypeEqualityFunc(self, typeobj, function):
391        """Add a type specific assertEqual style function to compare a type.
392
393        This method is for use by TestCase subclasses that need to register
394        their own type equality functions to provide nicer error messages.
395
396        Args:
397            typeobj: The data type to call this function on when both values
398                    are of the same type in assertEqual().
399            function: The callable taking two arguments and an optional
400                    msg= argument that raises self.failureException with a
401                    useful error message when the two arguments are not equal.
402        """
403        self._type_equality_funcs[typeobj] = function
404
405    def addCleanup(self, function, /, *args, **kwargs):
406        """Add a function, with arguments, to be called when the test is
407        completed. Functions added are called on a LIFO basis and are
408        called after tearDown on test failure or success.
409
410        Cleanup items are called even if setUp fails (unlike tearDown)."""
411        self._cleanups.append((function, args, kwargs))
412
413    @classmethod
414    def addClassCleanup(cls, function, /, *args, **kwargs):
415        """Same as addCleanup, except the cleanup items are called even if
416        setUpClass fails (unlike tearDownClass)."""
417        cls._class_cleanups.append((function, args, kwargs))
418
419    def setUp(self):
420        "Hook method for setting up the test fixture before exercising it."
421        pass
422
423    def tearDown(self):
424        "Hook method for deconstructing the test fixture after testing it."
425        pass
426
427    @classmethod
428    def setUpClass(cls):
429        "Hook method for setting up class fixture before running tests in the class."
430
431    @classmethod
432    def tearDownClass(cls):
433        "Hook method for deconstructing the class fixture after running all tests in the class."
434
435    def countTestCases(self):
436        return 1
437
438    def defaultTestResult(self):
439        return result.TestResult()
440
441    def shortDescription(self):
442        """Returns a one-line description of the test, or None if no
443        description has been provided.
444
445        The default implementation of this method returns the first line of
446        the specified test method's docstring.
447        """
448        doc = self._testMethodDoc
449        return doc.strip().split("\n")[0].strip() if doc else None
450
451
452    def id(self):
453        return "%s.%s" % (strclass(self.__class__), self._testMethodName)
454
455    def __eq__(self, other):
456        if type(self) is not type(other):
457            return NotImplemented
458
459        return self._testMethodName == other._testMethodName
460
461    def __hash__(self):
462        return hash((type(self), self._testMethodName))
463
464    def __str__(self):
465        return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
466
467    def __repr__(self):
468        return "<%s testMethod=%s>" % \
469               (strclass(self.__class__), self._testMethodName)
470
471    def _addSkip(self, result, test_case, reason):
472        addSkip = getattr(result, 'addSkip', None)
473        if addSkip is not None:
474            addSkip(test_case, reason)
475        else:
476            warnings.warn("TestResult has no addSkip method, skips not reported",
477                          RuntimeWarning, 2)
478            result.addSuccess(test_case)
479
480    @contextlib.contextmanager
481    def subTest(self, msg=_subtest_msg_sentinel, **params):
482        """Return a context manager that will return the enclosed block
483        of code in a subtest identified by the optional message and
484        keyword parameters.  A failure in the subtest marks the test
485        case as failed but resumes execution at the end of the enclosed
486        block, allowing further test code to be executed.
487        """
488        if self._outcome is None or not self._outcome.result_supports_subtests:
489            yield
490            return
491        parent = self._subtest
492        if parent is None:
493            params_map = _OrderedChainMap(params)
494        else:
495            params_map = parent.params.new_child(params)
496        self._subtest = _SubTest(self, msg, params_map)
497        try:
498            with self._outcome.testPartExecutor(self._subtest, isTest=True):
499                yield
500            if not self._outcome.success:
501                result = self._outcome.result
502                if result is not None and result.failfast:
503                    raise _ShouldStop
504            elif self._outcome.expectedFailure:
505                # If the test is expecting a failure, we really want to
506                # stop now and register the expected failure.
507                raise _ShouldStop
508        finally:
509            self._subtest = parent
510
511    def _feedErrorsToResult(self, result, errors):
512        for test, exc_info in errors:
513            if isinstance(test, _SubTest):
514                result.addSubTest(test.test_case, test, exc_info)
515            elif exc_info is not None:
516                if issubclass(exc_info[0], self.failureException):
517                    result.addFailure(test, exc_info)
518                else:
519                    result.addError(test, exc_info)
520
521    def _addExpectedFailure(self, result, exc_info):
522        try:
523            addExpectedFailure = result.addExpectedFailure
524        except AttributeError:
525            warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
526                          RuntimeWarning)
527            result.addSuccess(self)
528        else:
529            addExpectedFailure(self, exc_info)
530
531    def _addUnexpectedSuccess(self, result):
532        try:
533            addUnexpectedSuccess = result.addUnexpectedSuccess
534        except AttributeError:
535            warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
536                          RuntimeWarning)
537            # We need to pass an actual exception and traceback to addFailure,
538            # otherwise the legacy result can choke.
539            try:
540                raise _UnexpectedSuccess from None
541            except _UnexpectedSuccess:
542                result.addFailure(self, sys.exc_info())
543        else:
544            addUnexpectedSuccess(self)
545
546    def _callSetUp(self):
547        self.setUp()
548
549    def _callTestMethod(self, method):
550        method()
551
552    def _callTearDown(self):
553        self.tearDown()
554
555    def _callCleanup(self, function, /, *args, **kwargs):
556        function(*args, **kwargs)
557
558    def run(self, result=None):
559        if result is None:
560            result = self.defaultTestResult()
561            startTestRun = getattr(result, 'startTestRun', None)
562            stopTestRun = getattr(result, 'stopTestRun', None)
563            if startTestRun is not None:
564                startTestRun()
565        else:
566            stopTestRun = None
567
568        result.startTest(self)
569        try:
570            testMethod = getattr(self, self._testMethodName)
571            if (getattr(self.__class__, "__unittest_skip__", False) or
572                getattr(testMethod, "__unittest_skip__", False)):
573                # If the class or method was skipped.
574                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
575                            or getattr(testMethod, '__unittest_skip_why__', ''))
576                self._addSkip(result, self, skip_why)
577                return result
578
579            expecting_failure = (
580                getattr(self, "__unittest_expecting_failure__", False) or
581                getattr(testMethod, "__unittest_expecting_failure__", False)
582            )
583            outcome = _Outcome(result)
584            try:
585                self._outcome = outcome
586
587                with outcome.testPartExecutor(self):
588                    self._callSetUp()
589                if outcome.success:
590                    outcome.expecting_failure = expecting_failure
591                    with outcome.testPartExecutor(self, isTest=True):
592                        self._callTestMethod(testMethod)
593                    outcome.expecting_failure = False
594                    with outcome.testPartExecutor(self):
595                        self._callTearDown()
596
597                self.doCleanups()
598                for test, reason in outcome.skipped:
599                    self._addSkip(result, test, reason)
600                self._feedErrorsToResult(result, outcome.errors)
601                if outcome.success:
602                    if expecting_failure:
603                        if outcome.expectedFailure:
604                            self._addExpectedFailure(result, outcome.expectedFailure)
605                        else:
606                            self._addUnexpectedSuccess(result)
607                    else:
608                        result.addSuccess(self)
609                return result
610            finally:
611                # explicitly break reference cycles:
612                # outcome.errors -> frame -> outcome -> outcome.errors
613                # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
614                outcome.errors.clear()
615                outcome.expectedFailure = None
616
617                # clear the outcome, no more needed
618                self._outcome = None
619
620        finally:
621            result.stopTest(self)
622            if stopTestRun is not None:
623                stopTestRun()
624
625    def doCleanups(self):
626        """Execute all cleanup functions. Normally called for you after
627        tearDown."""
628        outcome = self._outcome or _Outcome()
629        while self._cleanups:
630            function, args, kwargs = self._cleanups.pop()
631            with outcome.testPartExecutor(self):
632                self._callCleanup(function, *args, **kwargs)
633
634        # return this for backwards compatibility
635        # even though we no longer use it internally
636        return outcome.success
637
638    @classmethod
639    def doClassCleanups(cls):
640        """Execute all class cleanup functions. Normally called for you after
641        tearDownClass."""
642        cls.tearDown_exceptions = []
643        while cls._class_cleanups:
644            function, args, kwargs = cls._class_cleanups.pop()
645            try:
646                function(*args, **kwargs)
647            except Exception:
648                cls.tearDown_exceptions.append(sys.exc_info())
649
650    def __call__(self, *args, **kwds):
651        return self.run(*args, **kwds)
652
653    def debug(self):
654        """Run the test without collecting errors in a TestResult"""
655        testMethod = getattr(self, self._testMethodName)
656        if (getattr(self.__class__, "__unittest_skip__", False) or
657            getattr(testMethod, "__unittest_skip__", False)):
658            # If the class or method was skipped.
659            skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
660                        or getattr(testMethod, '__unittest_skip_why__', ''))
661            raise SkipTest(skip_why)
662
663        self._callSetUp()
664        self._callTestMethod(testMethod)
665        self._callTearDown()
666        while self._cleanups:
667            function, args, kwargs = self._cleanups.pop()
668            self._callCleanup(function, *args, **kwargs)
669
670    def skipTest(self, reason):
671        """Skip this test."""
672        raise SkipTest(reason)
673
674    def fail(self, msg=None):
675        """Fail immediately, with the given message."""
676        raise self.failureException(msg)
677
678    def assertFalse(self, expr, msg=None):
679        """Check that the expression is false."""
680        if expr:
681            msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
682            raise self.failureException(msg)
683
684    def assertTrue(self, expr, msg=None):
685        """Check that the expression is true."""
686        if not expr:
687            msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
688            raise self.failureException(msg)
689
690    def _formatMessage(self, msg, standardMsg):
691        """Honour the longMessage attribute when generating failure messages.
692        If longMessage is False this means:
693        * Use only an explicit message if it is provided
694        * Otherwise use the standard message for the assert
695
696        If longMessage is True:
697        * Use the standard message
698        * If an explicit message is provided, plus ' : ' and the explicit message
699        """
700        if not self.longMessage:
701            return msg or standardMsg
702        if msg is None:
703            return standardMsg
704        try:
705            # don't switch to '{}' formatting in Python 2.X
706            # it changes the way unicode input is handled
707            return '%s : %s' % (standardMsg, msg)
708        except UnicodeDecodeError:
709            return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
710
711    def assertRaises(self, expected_exception, *args, **kwargs):
712        """Fail unless an exception of class expected_exception is raised
713           by the callable when invoked with specified positional and
714           keyword arguments. If a different type of exception is
715           raised, it will not be caught, and the test case will be
716           deemed to have suffered an error, exactly as for an
717           unexpected exception.
718
719           If called with the callable and arguments omitted, will return a
720           context object used like this::
721
722                with self.assertRaises(SomeException):
723                    do_something()
724
725           An optional keyword argument 'msg' can be provided when assertRaises
726           is used as a context object.
727
728           The context manager keeps a reference to the exception as
729           the 'exception' attribute. This allows you to inspect the
730           exception after the assertion::
731
732               with self.assertRaises(SomeException) as cm:
733                   do_something()
734               the_exception = cm.exception
735               self.assertEqual(the_exception.error_code, 3)
736        """
737        context = _AssertRaisesContext(expected_exception, self)
738        try:
739            return context.handle('assertRaises', args, kwargs)
740        finally:
741            # bpo-23890: manually break a reference cycle
742            context = None
743
744    def assertWarns(self, expected_warning, *args, **kwargs):
745        """Fail unless a warning of class warnClass is triggered
746           by the callable when invoked with specified positional and
747           keyword arguments.  If a different type of warning is
748           triggered, it will not be handled: depending on the other
749           warning filtering rules in effect, it might be silenced, printed
750           out, or raised as an exception.
751
752           If called with the callable and arguments omitted, will return a
753           context object used like this::
754
755                with self.assertWarns(SomeWarning):
756                    do_something()
757
758           An optional keyword argument 'msg' can be provided when assertWarns
759           is used as a context object.
760
761           The context manager keeps a reference to the first matching
762           warning as the 'warning' attribute; similarly, the 'filename'
763           and 'lineno' attributes give you information about the line
764           of Python code from which the warning was triggered.
765           This allows you to inspect the warning after the assertion::
766
767               with self.assertWarns(SomeWarning) as cm:
768                   do_something()
769               the_warning = cm.warning
770               self.assertEqual(the_warning.some_attribute, 147)
771        """
772        context = _AssertWarnsContext(expected_warning, self)
773        return context.handle('assertWarns', args, kwargs)
774
775    def assertLogs(self, logger=None, level=None):
776        """Fail unless a log message of level *level* or higher is emitted
777        on *logger_name* or its children.  If omitted, *level* defaults to
778        INFO and *logger* defaults to the root logger.
779
780        This method must be used as a context manager, and will yield
781        a recording object with two attributes: `output` and `records`.
782        At the end of the context manager, the `output` attribute will
783        be a list of the matching formatted log messages and the
784        `records` attribute will be a list of the corresponding LogRecord
785        objects.
786
787        Example::
788
789            with self.assertLogs('foo', level='INFO') as cm:
790                logging.getLogger('foo').info('first message')
791                logging.getLogger('foo.bar').error('second message')
792            self.assertEqual(cm.output, ['INFO:foo:first message',
793                                         'ERROR:foo.bar:second message'])
794        """
795        # Lazy import to avoid importing logging if it is not needed.
796        from ._log import _AssertLogsContext
797        return _AssertLogsContext(self, logger, level)
798
799    def _getAssertEqualityFunc(self, first, second):
800        """Get a detailed comparison function for the types of the two args.
801
802        Returns: A callable accepting (first, second, msg=None) that will
803        raise a failure exception if first != second with a useful human
804        readable error message for those types.
805        """
806        #
807        # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
808        # and vice versa.  I opted for the conservative approach in case
809        # subclasses are not intended to be compared in detail to their super
810        # class instances using a type equality func.  This means testing
811        # subtypes won't automagically use the detailed comparison.  Callers
812        # should use their type specific assertSpamEqual method to compare
813        # subclasses if the detailed comparison is desired and appropriate.
814        # See the discussion in http://bugs.python.org/issue2578.
815        #
816        if type(first) is type(second):
817            asserter = self._type_equality_funcs.get(type(first))
818            if asserter is not None:
819                if isinstance(asserter, str):
820                    asserter = getattr(self, asserter)
821                return asserter
822
823        return self._baseAssertEqual
824
825    def _baseAssertEqual(self, first, second, msg=None):
826        """The default assertEqual implementation, not type specific."""
827        if not first == second:
828            standardMsg = '%s != %s' % _common_shorten_repr(first, second)
829            msg = self._formatMessage(msg, standardMsg)
830            raise self.failureException(msg)
831
832    def assertEqual(self, first, second, msg=None):
833        """Fail if the two objects are unequal as determined by the '=='
834           operator.
835        """
836        assertion_func = self._getAssertEqualityFunc(first, second)
837        assertion_func(first, second, msg=msg)
838
839    def assertNotEqual(self, first, second, msg=None):
840        """Fail if the two objects are equal as determined by the '!='
841           operator.
842        """
843        if not first != second:
844            msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
845                                                          safe_repr(second)))
846            raise self.failureException(msg)
847
848    def assertAlmostEqual(self, first, second, places=None, msg=None,
849                          delta=None):
850        """Fail if the two objects are unequal as determined by their
851           difference rounded to the given number of decimal places
852           (default 7) and comparing to zero, or by comparing that the
853           difference between the two objects is more than the given
854           delta.
855
856           Note that decimal places (from zero) are usually not the same
857           as significant digits (measured from the most significant digit).
858
859           If the two objects compare equal then they will automatically
860           compare almost equal.
861        """
862        if first == second:
863            # shortcut
864            return
865        if delta is not None and places is not None:
866            raise TypeError("specify delta or places not both")
867
868        diff = abs(first - second)
869        if delta is not None:
870            if diff <= delta:
871                return
872
873            standardMsg = '%s != %s within %s delta (%s difference)' % (
874                safe_repr(first),
875                safe_repr(second),
876                safe_repr(delta),
877                safe_repr(diff))
878        else:
879            if places is None:
880                places = 7
881
882            if round(diff, places) == 0:
883                return
884
885            standardMsg = '%s != %s within %r places (%s difference)' % (
886                safe_repr(first),
887                safe_repr(second),
888                places,
889                safe_repr(diff))
890        msg = self._formatMessage(msg, standardMsg)
891        raise self.failureException(msg)
892
893    def assertNotAlmostEqual(self, first, second, places=None, msg=None,
894                             delta=None):
895        """Fail if the two objects are equal as determined by their
896           difference rounded to the given number of decimal places
897           (default 7) and comparing to zero, or by comparing that the
898           difference between the two objects is less than the given delta.
899
900           Note that decimal places (from zero) are usually not the same
901           as significant digits (measured from the most significant digit).
902
903           Objects that are equal automatically fail.
904        """
905        if delta is not None and places is not None:
906            raise TypeError("specify delta or places not both")
907        diff = abs(first - second)
908        if delta is not None:
909            if not (first == second) and diff > delta:
910                return
911            standardMsg = '%s == %s within %s delta (%s difference)' % (
912                safe_repr(first),
913                safe_repr(second),
914                safe_repr(delta),
915                safe_repr(diff))
916        else:
917            if places is None:
918                places = 7
919            if not (first == second) and round(diff, places) != 0:
920                return
921            standardMsg = '%s == %s within %r places' % (safe_repr(first),
922                                                         safe_repr(second),
923                                                         places)
924
925        msg = self._formatMessage(msg, standardMsg)
926        raise self.failureException(msg)
927
928    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
929        """An equality assertion for ordered sequences (like lists and tuples).
930
931        For the purposes of this function, a valid ordered sequence type is one
932        which can be indexed, has a length, and has an equality operator.
933
934        Args:
935            seq1: The first sequence to compare.
936            seq2: The second sequence to compare.
937            seq_type: The expected datatype of the sequences, or None if no
938                    datatype should be enforced.
939            msg: Optional message to use on failure instead of a list of
940                    differences.
941        """
942        if seq_type is not None:
943            seq_type_name = seq_type.__name__
944            if not isinstance(seq1, seq_type):
945                raise self.failureException('First sequence is not a %s: %s'
946                                        % (seq_type_name, safe_repr(seq1)))
947            if not isinstance(seq2, seq_type):
948                raise self.failureException('Second sequence is not a %s: %s'
949                                        % (seq_type_name, safe_repr(seq2)))
950        else:
951            seq_type_name = "sequence"
952
953        differing = None
954        try:
955            len1 = len(seq1)
956        except (TypeError, NotImplementedError):
957            differing = 'First %s has no length.    Non-sequence?' % (
958                    seq_type_name)
959
960        if differing is None:
961            try:
962                len2 = len(seq2)
963            except (TypeError, NotImplementedError):
964                differing = 'Second %s has no length.    Non-sequence?' % (
965                        seq_type_name)
966
967        if differing is None:
968            if seq1 == seq2:
969                return
970
971            differing = '%ss differ: %s != %s\n' % (
972                    (seq_type_name.capitalize(),) +
973                    _common_shorten_repr(seq1, seq2))
974
975            for i in range(min(len1, len2)):
976                try:
977                    item1 = seq1[i]
978                except (TypeError, IndexError, NotImplementedError):
979                    differing += ('\nUnable to index element %d of first %s\n' %
980                                 (i, seq_type_name))
981                    break
982
983                try:
984                    item2 = seq2[i]
985                except (TypeError, IndexError, NotImplementedError):
986                    differing += ('\nUnable to index element %d of second %s\n' %
987                                 (i, seq_type_name))
988                    break
989
990                if item1 != item2:
991                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
992                                 ((i,) + _common_shorten_repr(item1, item2)))
993                    break
994            else:
995                if (len1 == len2 and seq_type is None and
996                    type(seq1) != type(seq2)):
997                    # The sequences are the same, but have differing types.
998                    return
999
1000            if len1 > len2:
1001                differing += ('\nFirst %s contains %d additional '
1002                             'elements.\n' % (seq_type_name, len1 - len2))
1003                try:
1004                    differing += ('First extra element %d:\n%s\n' %
1005                                  (len2, safe_repr(seq1[len2])))
1006                except (TypeError, IndexError, NotImplementedError):
1007                    differing += ('Unable to index element %d '
1008                                  'of first %s\n' % (len2, seq_type_name))
1009            elif len1 < len2:
1010                differing += ('\nSecond %s contains %d additional '
1011                             'elements.\n' % (seq_type_name, len2 - len1))
1012                try:
1013                    differing += ('First extra element %d:\n%s\n' %
1014                                  (len1, safe_repr(seq2[len1])))
1015                except (TypeError, IndexError, NotImplementedError):
1016                    differing += ('Unable to index element %d '
1017                                  'of second %s\n' % (len1, seq_type_name))
1018        standardMsg = differing
1019        diffMsg = '\n' + '\n'.join(
1020            difflib.ndiff(pprint.pformat(seq1).splitlines(),
1021                          pprint.pformat(seq2).splitlines()))
1022
1023        standardMsg = self._truncateMessage(standardMsg, diffMsg)
1024        msg = self._formatMessage(msg, standardMsg)
1025        self.fail(msg)
1026
1027    def _truncateMessage(self, message, diff):
1028        max_diff = self.maxDiff
1029        if max_diff is None or len(diff) <= max_diff:
1030            return message + diff
1031        return message + (DIFF_OMITTED % len(diff))
1032
1033    def assertListEqual(self, list1, list2, msg=None):
1034        """A list-specific equality assertion.
1035
1036        Args:
1037            list1: The first list to compare.
1038            list2: The second list to compare.
1039            msg: Optional message to use on failure instead of a list of
1040                    differences.
1041
1042        """
1043        self.assertSequenceEqual(list1, list2, msg, seq_type=list)
1044
1045    def assertTupleEqual(self, tuple1, tuple2, msg=None):
1046        """A tuple-specific equality assertion.
1047
1048        Args:
1049            tuple1: The first tuple to compare.
1050            tuple2: The second tuple to compare.
1051            msg: Optional message to use on failure instead of a list of
1052                    differences.
1053        """
1054        self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
1055
1056    def assertSetEqual(self, set1, set2, msg=None):
1057        """A set-specific equality assertion.
1058
1059        Args:
1060            set1: The first set to compare.
1061            set2: The second set to compare.
1062            msg: Optional message to use on failure instead of a list of
1063                    differences.
1064
1065        assertSetEqual uses ducktyping to support different types of sets, and
1066        is optimized for sets specifically (parameters must support a
1067        difference method).
1068        """
1069        try:
1070            difference1 = set1.difference(set2)
1071        except TypeError as e:
1072            self.fail('invalid type when attempting set difference: %s' % e)
1073        except AttributeError as e:
1074            self.fail('first argument does not support set difference: %s' % e)
1075
1076        try:
1077            difference2 = set2.difference(set1)
1078        except TypeError as e:
1079            self.fail('invalid type when attempting set difference: %s' % e)
1080        except AttributeError as e:
1081            self.fail('second argument does not support set difference: %s' % e)
1082
1083        if not (difference1 or difference2):
1084            return
1085
1086        lines = []
1087        if difference1:
1088            lines.append('Items in the first set but not the second:')
1089            for item in difference1:
1090                lines.append(repr(item))
1091        if difference2:
1092            lines.append('Items in the second set but not the first:')
1093            for item in difference2:
1094                lines.append(repr(item))
1095
1096        standardMsg = '\n'.join(lines)
1097        self.fail(self._formatMessage(msg, standardMsg))
1098
1099    def assertIn(self, member, container, msg=None):
1100        """Just like self.assertTrue(a in b), but with a nicer default message."""
1101        if member not in container:
1102            standardMsg = '%s not found in %s' % (safe_repr(member),
1103                                                  safe_repr(container))
1104            self.fail(self._formatMessage(msg, standardMsg))
1105
1106    def assertNotIn(self, member, container, msg=None):
1107        """Just like self.assertTrue(a not in b), but with a nicer default message."""
1108        if member in container:
1109            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
1110                                                        safe_repr(container))
1111            self.fail(self._formatMessage(msg, standardMsg))
1112
1113    def assertIs(self, expr1, expr2, msg=None):
1114        """Just like self.assertTrue(a is b), but with a nicer default message."""
1115        if expr1 is not expr2:
1116            standardMsg = '%s is not %s' % (safe_repr(expr1),
1117                                             safe_repr(expr2))
1118            self.fail(self._formatMessage(msg, standardMsg))
1119
1120    def assertIsNot(self, expr1, expr2, msg=None):
1121        """Just like self.assertTrue(a is not b), but with a nicer default message."""
1122        if expr1 is expr2:
1123            standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
1124            self.fail(self._formatMessage(msg, standardMsg))
1125
1126    def assertDictEqual(self, d1, d2, msg=None):
1127        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
1128        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
1129
1130        if d1 != d2:
1131            standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
1132            diff = ('\n' + '\n'.join(difflib.ndiff(
1133                           pprint.pformat(d1).splitlines(),
1134                           pprint.pformat(d2).splitlines())))
1135            standardMsg = self._truncateMessage(standardMsg, diff)
1136            self.fail(self._formatMessage(msg, standardMsg))
1137
1138    def assertDictContainsSubset(self, subset, dictionary, msg=None):
1139        """Checks whether dictionary is a superset of subset."""
1140        warnings.warn('assertDictContainsSubset is deprecated',
1141                      DeprecationWarning)
1142        missing = []
1143        mismatched = []
1144        for key, value in subset.items():
1145            if key not in dictionary:
1146                missing.append(key)
1147            elif value != dictionary[key]:
1148                mismatched.append('%s, expected: %s, actual: %s' %
1149                                  (safe_repr(key), safe_repr(value),
1150                                   safe_repr(dictionary[key])))
1151
1152        if not (missing or mismatched):
1153            return
1154
1155        standardMsg = ''
1156        if missing:
1157            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
1158                                                    missing)
1159        if mismatched:
1160            if standardMsg:
1161                standardMsg += '; '
1162            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
1163
1164        self.fail(self._formatMessage(msg, standardMsg))
1165
1166
1167    def assertCountEqual(self, first, second, msg=None):
1168        """Asserts that two iterables have the same elements, the same number of
1169        times, without regard to order.
1170
1171            self.assertEqual(Counter(list(first)),
1172                             Counter(list(second)))
1173
1174         Example:
1175            - [0, 1, 1] and [1, 0, 1] compare equal.
1176            - [0, 0, 1] and [0, 1] compare unequal.
1177
1178        """
1179        first_seq, second_seq = list(first), list(second)
1180        try:
1181            first = collections.Counter(first_seq)
1182            second = collections.Counter(second_seq)
1183        except TypeError:
1184            # Handle case with unhashable elements
1185            differences = _count_diff_all_purpose(first_seq, second_seq)
1186        else:
1187            if first == second:
1188                return
1189            differences = _count_diff_hashable(first_seq, second_seq)
1190
1191        if differences:
1192            standardMsg = 'Element counts were not equal:\n'
1193            lines = ['First has %d, Second has %d:  %r' % diff for diff in differences]
1194            diffMsg = '\n'.join(lines)
1195            standardMsg = self._truncateMessage(standardMsg, diffMsg)
1196            msg = self._formatMessage(msg, standardMsg)
1197            self.fail(msg)
1198
1199    def assertMultiLineEqual(self, first, second, msg=None):
1200        """Assert that two multi-line strings are equal."""
1201        self.assertIsInstance(first, str, 'First argument is not a string')
1202        self.assertIsInstance(second, str, 'Second argument is not a string')
1203
1204        if first != second:
1205            # don't use difflib if the strings are too long
1206            if (len(first) > self._diffThreshold or
1207                len(second) > self._diffThreshold):
1208                self._baseAssertEqual(first, second, msg)
1209            firstlines = first.splitlines(keepends=True)
1210            secondlines = second.splitlines(keepends=True)
1211            if len(firstlines) == 1 and first.strip('\r\n') == first:
1212                firstlines = [first + '\n']
1213                secondlines = [second + '\n']
1214            standardMsg = '%s != %s' % _common_shorten_repr(first, second)
1215            diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
1216            standardMsg = self._truncateMessage(standardMsg, diff)
1217            self.fail(self._formatMessage(msg, standardMsg))
1218
1219    def assertLess(self, a, b, msg=None):
1220        """Just like self.assertTrue(a < b), but with a nicer default message."""
1221        if not a < b:
1222            standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
1223            self.fail(self._formatMessage(msg, standardMsg))
1224
1225    def assertLessEqual(self, a, b, msg=None):
1226        """Just like self.assertTrue(a <= b), but with a nicer default message."""
1227        if not a <= b:
1228            standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
1229            self.fail(self._formatMessage(msg, standardMsg))
1230
1231    def assertGreater(self, a, b, msg=None):
1232        """Just like self.assertTrue(a > b), but with a nicer default message."""
1233        if not a > b:
1234            standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
1235            self.fail(self._formatMessage(msg, standardMsg))
1236
1237    def assertGreaterEqual(self, a, b, msg=None):
1238        """Just like self.assertTrue(a >= b), but with a nicer default message."""
1239        if not a >= b:
1240            standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
1241            self.fail(self._formatMessage(msg, standardMsg))
1242
1243    def assertIsNone(self, obj, msg=None):
1244        """Same as self.assertTrue(obj is None), with a nicer default message."""
1245        if obj is not None:
1246            standardMsg = '%s is not None' % (safe_repr(obj),)
1247            self.fail(self._formatMessage(msg, standardMsg))
1248
1249    def assertIsNotNone(self, obj, msg=None):
1250        """Included for symmetry with assertIsNone."""
1251        if obj is None:
1252            standardMsg = 'unexpectedly None'
1253            self.fail(self._formatMessage(msg, standardMsg))
1254
1255    def assertIsInstance(self, obj, cls, msg=None):
1256        """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1257        default message."""
1258        if not isinstance(obj, cls):
1259            standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
1260            self.fail(self._formatMessage(msg, standardMsg))
1261
1262    def assertNotIsInstance(self, obj, cls, msg=None):
1263        """Included for symmetry with assertIsInstance."""
1264        if isinstance(obj, cls):
1265            standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
1266            self.fail(self._formatMessage(msg, standardMsg))
1267
1268    def assertRaisesRegex(self, expected_exception, expected_regex,
1269                          *args, **kwargs):
1270        """Asserts that the message in a raised exception matches a regex.
1271
1272        Args:
1273            expected_exception: Exception class expected to be raised.
1274            expected_regex: Regex (re.Pattern object or string) expected
1275                    to be found in error message.
1276            args: Function to be called and extra positional args.
1277            kwargs: Extra kwargs.
1278            msg: Optional message used in case of failure. Can only be used
1279                    when assertRaisesRegex is used as a context manager.
1280        """
1281        context = _AssertRaisesContext(expected_exception, self, expected_regex)
1282        return context.handle('assertRaisesRegex', args, kwargs)
1283
1284    def assertWarnsRegex(self, expected_warning, expected_regex,
1285                         *args, **kwargs):
1286        """Asserts that the message in a triggered warning matches a regexp.
1287        Basic functioning is similar to assertWarns() with the addition
1288        that only warnings whose messages also match the regular expression
1289        are considered successful matches.
1290
1291        Args:
1292            expected_warning: Warning class expected to be triggered.
1293            expected_regex: Regex (re.Pattern object or string) expected
1294                    to be found in error message.
1295            args: Function to be called and extra positional args.
1296            kwargs: Extra kwargs.
1297            msg: Optional message used in case of failure. Can only be used
1298                    when assertWarnsRegex is used as a context manager.
1299        """
1300        context = _AssertWarnsContext(expected_warning, self, expected_regex)
1301        return context.handle('assertWarnsRegex', args, kwargs)
1302
1303    def assertRegex(self, text, expected_regex, msg=None):
1304        """Fail the test unless the text matches the regular expression."""
1305        if isinstance(expected_regex, (str, bytes)):
1306            assert expected_regex, "expected_regex must not be empty."
1307            expected_regex = re.compile(expected_regex)
1308        if not expected_regex.search(text):
1309            standardMsg = "Regex didn't match: %r not found in %r" % (
1310                expected_regex.pattern, text)
1311            # _formatMessage ensures the longMessage option is respected
1312            msg = self._formatMessage(msg, standardMsg)
1313            raise self.failureException(msg)
1314
1315    def assertNotRegex(self, text, unexpected_regex, msg=None):
1316        """Fail the test if the text matches the regular expression."""
1317        if isinstance(unexpected_regex, (str, bytes)):
1318            unexpected_regex = re.compile(unexpected_regex)
1319        match = unexpected_regex.search(text)
1320        if match:
1321            standardMsg = 'Regex matched: %r matches %r in %r' % (
1322                text[match.start() : match.end()],
1323                unexpected_regex.pattern,
1324                text)
1325            # _formatMessage ensures the longMessage option is respected
1326            msg = self._formatMessage(msg, standardMsg)
1327            raise self.failureException(msg)
1328
1329
1330    def _deprecate(original_func):
1331        def deprecated_func(*args, **kwargs):
1332            warnings.warn(
1333                'Please use {0} instead.'.format(original_func.__name__),
1334                DeprecationWarning, 2)
1335            return original_func(*args, **kwargs)
1336        return deprecated_func
1337
1338    # see #9424
1339    failUnlessEqual = assertEquals = _deprecate(assertEqual)
1340    failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1341    failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1342    failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1343    failUnless = assert_ = _deprecate(assertTrue)
1344    failUnlessRaises = _deprecate(assertRaises)
1345    failIf = _deprecate(assertFalse)
1346    assertRaisesRegexp = _deprecate(assertRaisesRegex)
1347    assertRegexpMatches = _deprecate(assertRegex)
1348    assertNotRegexpMatches = _deprecate(assertNotRegex)
1349
1350
1351
1352class FunctionTestCase(TestCase):
1353    """A test case that wraps a test function.
1354
1355    This is useful for slipping pre-existing test functions into the
1356    unittest framework. Optionally, set-up and tidy-up functions can be
1357    supplied. As with TestCase, the tidy-up ('tearDown') function will
1358    always be called if the set-up ('setUp') function ran successfully.
1359    """
1360
1361    def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1362        super(FunctionTestCase, self).__init__()
1363        self._setUpFunc = setUp
1364        self._tearDownFunc = tearDown
1365        self._testFunc = testFunc
1366        self._description = description
1367
1368    def setUp(self):
1369        if self._setUpFunc is not None:
1370            self._setUpFunc()
1371
1372    def tearDown(self):
1373        if self._tearDownFunc is not None:
1374            self._tearDownFunc()
1375
1376    def runTest(self):
1377        self._testFunc()
1378
1379    def id(self):
1380        return self._testFunc.__name__
1381
1382    def __eq__(self, other):
1383        if not isinstance(other, self.__class__):
1384            return NotImplemented
1385
1386        return self._setUpFunc == other._setUpFunc and \
1387               self._tearDownFunc == other._tearDownFunc and \
1388               self._testFunc == other._testFunc and \
1389               self._description == other._description
1390
1391    def __hash__(self):
1392        return hash((type(self), self._setUpFunc, self._tearDownFunc,
1393                     self._testFunc, self._description))
1394
1395    def __str__(self):
1396        return "%s (%s)" % (strclass(self.__class__),
1397                            self._testFunc.__name__)
1398
1399    def __repr__(self):
1400        return "<%s tec=%s>" % (strclass(self.__class__),
1401                                     self._testFunc)
1402
1403    def shortDescription(self):
1404        if self._description is not None:
1405            return self._description
1406        doc = self._testFunc.__doc__
1407        return doc and doc.split("\n")[0].strip() or None
1408
1409
1410class _SubTest(TestCase):
1411
1412    def __init__(self, test_case, message, params):
1413        super().__init__()
1414        self._message = message
1415        self.test_case = test_case
1416        self.params = params
1417        self.failureException = test_case.failureException
1418
1419    def runTest(self):
1420        raise NotImplementedError("subtests cannot be run directly")
1421
1422    def _subDescription(self):
1423        parts = []
1424        if self._message is not _subtest_msg_sentinel:
1425            parts.append("[{}]".format(self._message))
1426        if self.params:
1427            params_desc = ', '.join(
1428                "{}={!r}".format(k, v)
1429                for (k, v) in self.params.items())
1430            parts.append("({})".format(params_desc))
1431        return " ".join(parts) or '(<subtest>)'
1432
1433    def id(self):
1434        return "{} {}".format(self.test_case.id(), self._subDescription())
1435
1436    def shortDescription(self):
1437        """Returns a one-line description of the subtest, or None if no
1438        description has been provided.
1439        """
1440        return self.test_case.shortDescription()
1441
1442    def __str__(self):
1443        return "{} {}".format(self.test_case, self._subDescription())
1444