github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/third_party/stdlib/unittest_runner.py (about)

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