Home | History | Annotate | Download | only in test
      1 """Monkey patch lame-o vanilla unittest with test skip feature.
      2 
      3 From the patch that was never applied (shameful!):
      4 http://bugs.python.org/issue1034053
      5 """
      6 
      7 import time, unittest
      8 
      9 
     10 class SkipException(Exception):
     11     pass
     12 
     13 
     14 def TestResult__init__(self):
     15     self.failures = []
     16     self.errors = []
     17     self.skipped = []
     18     self.testsRun = 0
     19     self.shouldStop = 0
     20 
     21 unittest.TestResult.__init__ = TestResult__init__
     22 
     23 
     24 def TestResult_addSkipped(self, test, err):
     25     """Called when a test is skipped.
     26 
     27     'err' is a tuple of values as returned by sys.exc_info().
     28     """
     29     self.skipped.append((test, str(err[1])))
     30 
     31 unittest.TestResult.addSkipped = TestResult_addSkipped
     32 
     33 
     34 def TestResult__repr__(self):
     35     return "<%s run=%i errors=%i failures=%i skipped=%i>" % (
     36         unittest._strclass(self.__class__), self.testsRun,
     37         len(self.errors), len(self.failures), len(self.skipped))
     38 
     39 unittest.TestResult.__repr__ = TestResult__repr__
     40 
     41 
     42 class TestCase(unittest.TestCase):
     43     # Yuck, all of run has to be copied for this.
     44     # I don't care about wrapping setUp atm.
     45     def run(self, result=None):
     46         if result is None: result = self.defaultTestResult()
     47         result.startTest(self)
     48         # Support variable naming differences between 2.4 and 2.6
     49         # Yay for silly variable hiding
     50         try:
     51             testMethodName = self.__testMethodName
     52             exc_info = self.__exc_info
     53         except AttributeError:
     54             testMethodName = self._testMethodName
     55             exc_info = self._exc_info
     56 
     57         testMethod = getattr(self, testMethodName)
     58 
     59         try:
     60             try:
     61                 self.setUp()
     62             except KeyboardInterrupt:
     63                 raise
     64             except:
     65                 result.addError(self, exc_info())
     66                 return
     67 
     68             ok = False
     69             try:
     70                 testMethod()
     71                 ok = True
     72             except self.failureException:
     73                 result.addFailure(self, exc_info())
     74             except SkipException:
     75                 result.addSkipped(self, exc_info())
     76             except KeyboardInterrupt:
     77                 raise
     78             except:
     79                 result.addError(self, exc_info())
     80 
     81             try:
     82                 self.tearDown()
     83             except KeyboardInterrupt:
     84                 raise
     85             except:
     86                 result.addError(self, exc_info())
     87                 ok = False
     88             if ok: result.addSuccess(self)
     89         finally:
     90             result.stopTest(self)
     91 
     92 
     93     def skip(self, msg=None):
     94         """Skip the test, with the given message."""
     95         raise SkipException(msg)
     96 
     97 
     98     def skipIf(self, expr, msg=None):
     99         """Skip the test if the expression is true."""
    100         if expr:
    101             raise SkipException(msg)
    102 
    103 
    104 def _TextTestResult_addSkipped(self, test, err):
    105     unittest.TestResult.addSkipped(self, test, err)
    106     if self.showAll:
    107         msg = str(err[1])
    108         if msg:
    109             msg = " (" + msg + ")"
    110         self.stream.writeln("SKIPPED" + msg)
    111     elif self.dots:
    112         self.stream.write('S')
    113 
    114 unittest._TextTestResult.addSkipped = _TextTestResult_addSkipped
    115 
    116 
    117 # Bah
    118 def TextTestRunner_run(self, test):
    119     "Run the given test case or test suite."
    120     result = self._makeResult()
    121     startTime = time.time()
    122     test(result)
    123     stopTime = time.time()
    124     timeTaken = stopTime - startTime
    125     result.printErrors()
    126     self.stream.writeln(result.separator2)
    127     run = result.testsRun
    128     self.stream.writeln("Ran %d test%s in %.3fs" %
    129                         (run, run != 1 and "s" or "", timeTaken))
    130     self.stream.writeln()
    131     if not result.wasSuccessful():
    132         self.stream.write("FAILED (")
    133         failed, errored, skipped = map(
    134             len, (result.failures, result.errors, result.skipped))
    135         if failed:
    136             self.stream.write("failures=%d" % failed)
    137         if errored:
    138             if failed: self.stream.write(", ")
    139             self.stream.write("errors=%d" % errored)
    140         if skipped:
    141             self.stream.write(", skipped=%d" % skipped)
    142         self.stream.writeln(")")
    143     else:
    144         if result.skipped:
    145             self.stream.writeln(
    146                 "OK (skipped=%d)" % len(result.skipped))
    147         else:
    148             self.stream.writeln("OK")
    149     return result
    150 
    151 unittest.TextTestRunner.run = TextTestRunner_run
    152