From: Alec Warner Date: Tue, 6 Mar 2007 07:34:18 +0000 (-0000) Subject: Roll our own unittest framework to add skip support. X-Git-Tag: v2.2_pre1~1604 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=fc831137d4a93582bc23916ea5b993674970b1a9;p=portage.git Roll our own unittest framework to add skip support. svn path=/main/trunk/; revision=6181 --- diff --git a/pym/portage/tests/__init__.py b/pym/portage/tests/__init__.py index 5a69ae3ed..56fc869c2 100644 --- a/pym/portage/tests/__init__.py +++ b/pym/portage/tests/__init__.py @@ -3,19 +3,16 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -import os, unittest +import os, unittest, time +import portage.tests def main(): - - testDirs = ["util","versions", "dep"] - + testDirs = ["util","versions", "dep", "xpak"] suite = unittest.TestSuite() - basedir = os.path.dirname(__file__) for mydir in testDirs: suite.addTests(getTests(os.path.join(basedir, mydir), basedir) ) - - return unittest.TextTestRunner(verbosity=2).run(suite) + return portage.tests.TextTestRunner(verbosity=2).run(suite) def my_import(name): mod = __import__(name) @@ -49,6 +46,128 @@ def getTests( path, base_path ): raise return result +class SkipException(Exception): + pass + +class TextTestResult(unittest._TextTestResult): + """ + We need a subclass of unittest._TextTestResult to handle skipped + tests. + + This just adds an addSkip method that can be used to add + skipped tests to the result; these can be displayed later + by the test runner. + """ + + def __init__( self, stream, descriptions, verbosity ): + unittest._TextTestResult.__init__( self, stream, descriptions, verbosity ) + self.skipped = [] + + def addSkip( self, test, info ): + self.skipped.append((test,info)) + if self.showAll: + self.stream.writeln("FAIL AND SKIP") + elif self.dots: + self.stream.write(".") + + def printErrors( self ): + if self.dots or self.showAll: + self.stream.writeln() + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + self.printErrorList('SKIP', self.skipped) + +class TestCase(unittest.TestCase): + """ + We need a way to mark a unit test as "ok to fail" + This way someone can add a broken test and mark it as failed + and then fix the code later. This may not be a great approach + (broken code!!??!11oneone) but it does happen at times. + """ + + SkipException = SkipException + + def __init__(self, methodName='runTest'): + # This method exists because unittest.py in python 2.4 stores + # the methodName as __testMethodName while 2.5 uses + # _testMethodName. + self._testMethodName = methodName + unittest.TestCase.__init__(self, methodName) + + def defaultTestResult(self): + return TextTestResult() + + def run( self, result=None ): + if result is None: result = self.defaultTestResult() + result.startTest(self) + testMethod = getattr(self, self._testMethodName) + try: + try: + self.setUp() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + return + ok = False + try: + testMethod() + ok = True + except self.failureException: + result.addFailure(self, self._exc_info()) + except self.SkipException: + result.addSkip(self,"%s: Failed but Skippable" % testMethod) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + ok = False + if ok: result.addSuccess(self) + finally: + result.stopTest(self) + +class TextTestRunner(unittest.TextTestRunner): + """ + We subclass unittest.TextTestRunner to output SKIP for tests that fail but are skippable + """ + + def _makeResult(self): + return TextTestResult(self.stream, self.descriptions, self.verbosity) + + def run( self, test ): + """ + Run the given test case or test suite. + """ + result = self._makeResult() + startTime = time.time() + test(result) + stopTime = time.time() + timeTaken = stopTime - startTime + result.printErrors() + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run != 1 and "s" or "", timeTaken)) + self.stream.writeln() + if not result.wasSuccessful(): + self.stream.write("FAILED (") + failed, errored = map(len, (result.failures, result.errors)) + if failed: + self.stream.write("failures=%d" % failed) + if errored: + if failed: self.stream.write(", ") + self.stream.write("errors=%d" % errored) + self.stream.writeln(")") + else: + self.stream.writeln("OK") + return result + test_cps = ['sys-apps/portage','virtual/portage'] test_versions = ['1.0', '1.0-r1','2.3_p4','1.0_alpha57'] test_slots = [ None, '1','gentoo-sources-2.6.17','spankywashere']