Home | History | Annotate | Download | only in unittest2
      1 """Running tests"""
      2 
      3 import sys
      4 import time
      5 import unittest
      6 
      7 from unittest2 import result
      8 
      9 try:
     10     from unittest2.signals import registerResult
     11 except ImportError:
     12     def registerResult(_):
     13         pass
     14 
     15 __unittest = True
     16 
     17 
     18 class _WritelnDecorator(object):
     19     """Used to decorate file-like objects with a handy 'writeln' method"""
     20     def __init__(self,stream):
     21         self.stream = stream
     22 
     23     def __getattr__(self, attr):
     24         if attr in ('stream', '__getstate__'):
     25             raise AttributeError(attr)
     26         return getattr(self.stream,attr)
     27 
     28     def writeln(self, arg=None):
     29         if arg:
     30             self.write(arg)
     31         self.write('\n') # text-mode streams translate to \r\n if needed
     32 
     33 
     34 class TextTestResult(result.TestResult):
     35     """A test result class that can print formatted text results to a stream.
     36 
     37     Used by TextTestRunner.
     38     """
     39     separator1 = '=' * 70
     40     separator2 = '-' * 70
     41 
     42     def __init__(self, stream, descriptions, verbosity):
     43         super(TextTestResult, self).__init__()
     44         self.stream = stream
     45         self.showAll = verbosity > 1
     46         self.dots = verbosity == 1
     47         self.descriptions = descriptions
     48 
     49     def getDescription(self, test):
     50         doc_first_line = test.shortDescription()
     51         if self.descriptions and doc_first_line:
     52             return '\n'.join((str(test), doc_first_line))
     53         else:
     54             return str(test)
     55 
     56     def startTest(self, test):
     57         super(TextTestResult, self).startTest(test)
     58         if self.showAll:
     59             self.stream.write(self.getDescription(test))
     60             self.stream.write(" ... ")
     61             self.stream.flush()
     62 
     63     def addSuccess(self, test):
     64         super(TextTestResult, self).addSuccess(test)
     65         if self.showAll:
     66             self.stream.writeln("ok")
     67         elif self.dots:
     68             self.stream.write('.')
     69             self.stream.flush()
     70 
     71     def addError(self, test, err):
     72         super(TextTestResult, self).addError(test, err)
     73         if self.showAll:
     74             self.stream.writeln("ERROR")
     75         elif self.dots:
     76             self.stream.write('E')
     77             self.stream.flush()
     78 
     79     def addFailure(self, test, err):
     80         super(TextTestResult, self).addFailure(test, err)
     81         if self.showAll:
     82             self.stream.writeln("FAIL")
     83         elif self.dots:
     84             self.stream.write('F')
     85             self.stream.flush()
     86 
     87     def addSkip(self, test, reason):
     88         super(TextTestResult, self).addSkip(test, reason)
     89         if self.showAll:
     90             self.stream.writeln("skipped %r" % (reason,))
     91         elif self.dots:
     92             self.stream.write("s")
     93             self.stream.flush()
     94 
     95     def addExpectedFailure(self, test, err):
     96         super(TextTestResult, self).addExpectedFailure(test, err)
     97         if self.showAll:
     98             self.stream.writeln("expected failure")
     99         elif self.dots:
    100             self.stream.write("x")
    101             self.stream.flush()
    102 
    103     def addUnexpectedSuccess(self, test):
    104         super(TextTestResult, self).addUnexpectedSuccess(test)
    105         if self.showAll:
    106             self.stream.writeln("unexpected success")
    107         elif self.dots:
    108             self.stream.write("u")
    109             self.stream.flush()
    110 
    111     def printErrors(self):
    112         if self.dots or self.showAll:
    113             self.stream.writeln()
    114         self.printErrorList('ERROR', self.errors)
    115         self.printErrorList('FAIL', self.failures)
    116 
    117     def printErrorList(self, flavour, errors):
    118         for test, err in errors:
    119             self.stream.writeln(self.separator1)
    120             self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
    121             self.stream.writeln(self.separator2)
    122             self.stream.writeln("%s" % err)
    123 
    124     def stopTestRun(self):
    125         super(TextTestResult, self).stopTestRun()
    126         self.printErrors()
    127 
    128 
    129 class TextTestRunner(unittest.TextTestRunner):
    130     """A test runner class that displays results in textual form.
    131 
    132     It prints out the names of tests as they are run, errors as they
    133     occur, and a summary of the results at the end of the test run.
    134     """
    135     resultclass = TextTestResult
    136 
    137     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
    138                     failfast=False, buffer=False, resultclass=None):
    139         self.stream = _WritelnDecorator(stream)
    140         self.descriptions = descriptions
    141         self.verbosity = verbosity
    142         self.failfast = failfast
    143         self.buffer = buffer
    144         if resultclass is not None:
    145             self.resultclass = resultclass
    146 
    147     def _makeResult(self):
    148         return self.resultclass(self.stream, self.descriptions, self.verbosity)
    149 
    150     def run(self, test):
    151         "Run the given test case or test suite."
    152         result = self._makeResult()
    153         result.failfast = self.failfast
    154         result.buffer = self.buffer
    155         registerResult(result)
    156 
    157         startTime = time.time()
    158         startTestRun = getattr(result, 'startTestRun', None)
    159         if startTestRun is not None:
    160             startTestRun()
    161         try:
    162             test(result)
    163         finally:
    164             stopTestRun = getattr(result, 'stopTestRun', None)
    165             if stopTestRun is not None:
    166                 stopTestRun()
    167             else:
    168                 result.printErrors()
    169         stopTime = time.time()
    170         timeTaken = stopTime - startTime
    171         if hasattr(result, 'separator2'):
    172             self.stream.writeln(result.separator2)
    173         run = result.testsRun
    174         self.stream.writeln("Ran %d test%s in %.3fs" %
    175                             (run, run != 1 and "s" or "", timeTaken))
    176         self.stream.writeln()
    177 
    178         expectedFails = unexpectedSuccesses = skipped = 0
    179         try:
    180             results = map(len, (result.expectedFailures,
    181                                 result.unexpectedSuccesses,
    182                                 result.skipped))
    183             expectedFails, unexpectedSuccesses, skipped = results
    184         except AttributeError:
    185             pass
    186         infos = []
    187         if not result.wasSuccessful():
    188             self.stream.write("FAILED")
    189             failed, errored = map(len, (result.failures, result.errors))
    190             if failed:
    191                 infos.append("failures=%d" % failed)
    192             if errored:
    193                 infos.append("errors=%d" % errored)
    194         else:
    195             self.stream.write("OK")
    196         if skipped:
    197             infos.append("skipped=%d" % skipped)
    198         if expectedFails:
    199             infos.append("expected failures=%d" % expectedFails)
    200         if unexpectedSuccesses:
    201             infos.append("unexpected successes=%d" % unexpectedSuccesses)
    202         if infos:
    203             self.stream.writeln(" (%s)" % (", ".join(infos),))
    204         else:
    205             self.stream.write("\n")
    206         return result
    207