mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Updated to latest PyUnit version (1.31 in PyUnit CVS); test_support.py
changed accordingly.
This commit is contained in:
		
							parent
							
								
									2e2cded1b5
								
							
						
					
					
						commit
						5ddd1a8dcb
					
				
					 2 changed files with 242 additions and 254 deletions
				
			
		|  | @ -102,12 +102,9 @@ def check_syntax(statement): | |||
| import unittest | ||||
| 
 | ||||
| 
 | ||||
| class BasicTestRunner(unittest.VerboseTextTestRunner): | ||||
|     def __init__(self, stream=sys.stderr): | ||||
|         unittest.VerboseTextTestRunner.__init__(self, stream, descriptions=0) | ||||
| 
 | ||||
| class BasicTestRunner: | ||||
|     def run(self, test): | ||||
|         result = unittest._VerboseTextTestResult(self.stream, descriptions=0) | ||||
|         result = unittest.TestResult() | ||||
|         test(result) | ||||
|         return result | ||||
| 
 | ||||
|  | @ -115,13 +112,12 @@ def run(self, test): | |||
| def run_unittest(testclass): | ||||
|     """Run tests from a unittest.TestCase-derived class.""" | ||||
|     if verbose: | ||||
|         f = sys.stdout | ||||
|         runner = unittest.TextTestRunner(sys.stdout, descriptions=0) | ||||
|     else: | ||||
|         import StringIO | ||||
|         f = StringIO.StringIO() | ||||
|         runner = BasicTestRunner() | ||||
| 
 | ||||
|     suite = unittest.makeSuite(testclass) | ||||
|     result = BasicTestRunner(stream=f).run(suite) | ||||
|     if result.errors or result.failures: | ||||
|     result = runner.run(suite) | ||||
|     if not result.wasSuccessful(): | ||||
|         raise TestFailed("errors occurred in %s.%s" | ||||
|                          % (testclass.__module__, testclass.__name__)) | ||||
|  |  | |||
							
								
								
									
										456
									
								
								Lib/unittest.py
									
										
									
									
									
								
							
							
						
						
									
										456
									
								
								Lib/unittest.py
									
										
									
									
									
								
							|  | @ -1,17 +1,32 @@ | |||
| #!/usr/bin/env python | ||||
| """ | ||||
| ''' | ||||
| Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's | ||||
| Smalltalk testing framework. | ||||
| 
 | ||||
| Further information is available in the bundled documentation, and from | ||||
| 
 | ||||
|   http://pyunit.sourceforge.net/ | ||||
| 
 | ||||
| This module contains the core framework classes that form the basis of | ||||
| specific test cases and suites (TestCase, TestSuite etc.), and also a | ||||
| text-based utility class for running the tests and reporting the results | ||||
| (TextTestRunner). | ||||
| 
 | ||||
| Simple usage: | ||||
| 
 | ||||
|     import unittest | ||||
| 
 | ||||
|     class IntegerArithmenticTestCase(unittest.TestCase): | ||||
|         def testAdd(self):  ## test method names begin 'test*' | ||||
|             self.assertEquals((1 + 2), 3) | ||||
|             self.assertEquals(0 + 1, 1) | ||||
|         def testMultiply(self); | ||||
|             self.assertEquals((0 * 10), 0) | ||||
|             self.assertEquals((5 * 8), 40) | ||||
| 
 | ||||
|     if __name__ == '__main__': | ||||
|         unittest.main() | ||||
| 
 | ||||
| Further information is available in the bundled documentation, and from | ||||
| 
 | ||||
|   http://pyunit.sourceforge.net/ | ||||
| 
 | ||||
| Copyright (c) 1999, 2000, 2001 Steve Purcell | ||||
| This module is free software, and you may redistribute it and/or modify | ||||
| it under the same terms as Python itself, so long as this copyright message | ||||
|  | @ -27,9 +42,10 @@ | |||
| PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, | ||||
| AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, | ||||
| SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||||
| """ | ||||
| ''' | ||||
| 
 | ||||
| __author__ = "Steve Purcell (stephen_purcell@yahoo.com)" | ||||
| __author__ = "Steve Purcell" | ||||
| __email__ = "stephen_purcell at yahoo dot com" | ||||
| __version__ = "$Revision$"[11:-2] | ||||
| 
 | ||||
| import time | ||||
|  | @ -37,15 +53,7 @@ | |||
| import traceback | ||||
| import string | ||||
| import os | ||||
| 
 | ||||
| ############################################################################## | ||||
| # A platform-specific concession to help the code work for JPython users | ||||
| ############################################################################## | ||||
| 
 | ||||
| plat = string.lower(sys.platform) | ||||
| _isJPython = string.find(plat, 'java') >= 0 or string.find(plat, 'jdk') >= 0 | ||||
| del plat | ||||
| 
 | ||||
| import types | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Test framework core | ||||
|  | @ -84,6 +92,10 @@ def addFailure(self, test, err): | |||
|         "Called when a failure has occurred" | ||||
|         self.failures.append((test, err)) | ||||
| 
 | ||||
|     def addSuccess(self, test): | ||||
|         "Called when a test has completed successfully" | ||||
|         pass | ||||
| 
 | ||||
|     def wasSuccessful(self): | ||||
|         "Tells whether or not this result was a success" | ||||
|         return len(self.failures) == len(self.errors) == 0 | ||||
|  | @ -101,10 +113,6 @@ def __repr__(self): | |||
| class TestCase: | ||||
|     """A class whose instances are single test cases. | ||||
| 
 | ||||
|     Test authors should subclass TestCase for their own tests. Construction  | ||||
|     and deconstruction of the test's environment ('fixture') can be | ||||
|     implemented by overriding the 'setUp' and 'tearDown' methods respectively. | ||||
| 
 | ||||
|     By default, the test code itself should be placed in a method named | ||||
|     'runTest'. | ||||
| 
 | ||||
|  | @ -112,6 +120,16 @@ class TestCase: | |||
|     many test methods as are needed. When instantiating such a TestCase | ||||
|     subclass, specify in the constructor arguments the name of the test method | ||||
|     that the instance is to execute. | ||||
| 
 | ||||
|     Test authors should subclass TestCase for their own tests. Construction  | ||||
|     and deconstruction of the test's environment ('fixture') can be | ||||
|     implemented by overriding the 'setUp' and 'tearDown' methods respectively. | ||||
| 
 | ||||
|     If it is necessary to override the __init__ method, the base class | ||||
|     __init__ method must always be called. It is important that subclasses | ||||
|     should not change the signature of their __init__ method, since instances | ||||
|     of the classes are instantiated automatically by parts of the framework | ||||
|     in order to be run. | ||||
|     """ | ||||
|     def __init__(self, methodName='runTest'): | ||||
|         """Create an instance of the class that will use the named test | ||||
|  | @ -119,7 +137,9 @@ def __init__(self, methodName='runTest'): | |||
|            not have a method with the specified name. | ||||
|         """ | ||||
|         try: | ||||
|             self.__testMethod = getattr(self,methodName) | ||||
|             self.__testMethodName = methodName | ||||
|             testMethod = getattr(self, methodName) | ||||
|             self.__testMethodDoc = testMethod.__doc__ | ||||
|         except AttributeError: | ||||
|             raise ValueError, "no such test method in %s: %s" % \ | ||||
|                   (self.__class__, methodName) | ||||
|  | @ -145,18 +165,18 @@ def shortDescription(self): | |||
|         The default implementation of this method returns the first line of | ||||
|         the specified test method's docstring. | ||||
|         """ | ||||
|         doc = self.__testMethod.__doc__ | ||||
|         doc = self.__testMethodDoc | ||||
|         return doc and string.strip(string.split(doc, "\n")[0]) or None | ||||
| 
 | ||||
|     def id(self): | ||||
|         return "%s.%s" % (self.__class__, self.__testMethod.__name__) | ||||
|         return "%s.%s" % (self.__class__, self.__testMethodName) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return "%s (%s)" % (self.__testMethod.__name__, self.__class__) | ||||
|         return "%s (%s)" % (self.__testMethodName, self.__class__) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return "<%s testMethod=%s>" % \ | ||||
|                (self.__class__, self.__testMethod.__name__) | ||||
|                (self.__class__, self.__testMethodName) | ||||
| 
 | ||||
|     def run(self, result=None): | ||||
|         return self(result) | ||||
|  | @ -164,6 +184,7 @@ def run(self, result=None): | |||
|     def __call__(self, result=None): | ||||
|         if result is None: result = self.defaultTestResult() | ||||
|         result.startTest(self) | ||||
|         testMethod = getattr(self, self.__testMethodName) | ||||
|         try: | ||||
|             try: | ||||
|                 self.setUp() | ||||
|  | @ -171,8 +192,10 @@ def __call__(self, result=None): | |||
|                 result.addError(self,self.__exc_info()) | ||||
|                 return | ||||
| 
 | ||||
|             ok = 0 | ||||
|             try: | ||||
|                 self.__testMethod() | ||||
|                 testMethod() | ||||
|                 ok = 1 | ||||
|             except AssertionError, e: | ||||
|                 result.addFailure(self,self.__exc_info()) | ||||
|             except: | ||||
|  | @ -182,12 +205,15 @@ def __call__(self, result=None): | |||
|                 self.tearDown() | ||||
|             except: | ||||
|                 result.addError(self,self.__exc_info()) | ||||
|                 ok = 0 | ||||
|             if ok: result.addSuccess(self) | ||||
|         finally: | ||||
|             result.stopTest(self) | ||||
| 
 | ||||
|     def debug(self): | ||||
|         """Run the test without collecting errors in a TestResult""" | ||||
|         self.setUp() | ||||
|         self.__testMethod() | ||||
|         getattr(self, self.__testMethodName)() | ||||
|         self.tearDown() | ||||
| 
 | ||||
|     def assert_(self, expr, msg=None): | ||||
|  | @ -220,6 +246,22 @@ def assertRaises(self, excClass, callableObj, *args, **kwargs): | |||
|             else: excName = str(excClass) | ||||
|             raise AssertionError, excName | ||||
| 
 | ||||
|     def assertEquals(self, first, second, msg=None): | ||||
|         """Assert that the two objects are equal as determined by the '==' | ||||
|            operator. | ||||
|         """ | ||||
|         self.assert_((first == second), msg or '%s != %s' % (first, second)) | ||||
| 
 | ||||
|     def assertNotEquals(self, first, second, msg=None): | ||||
|         """Assert that the two objects are unequal as determined by the '!=' | ||||
|            operator. | ||||
|         """ | ||||
|         self.assert_((first != second), msg or '%s == %s' % (first, second)) | ||||
| 
 | ||||
|     assertEqual = assertEquals | ||||
| 
 | ||||
|     assertNotEqual = assertNotEquals | ||||
| 
 | ||||
|     def fail(self, msg=None): | ||||
|         """Fail immediately, with the given message.""" | ||||
|         raise AssertionError, msg | ||||
|  | @ -278,10 +320,10 @@ def __call__(self, result): | |||
|         return result | ||||
| 
 | ||||
|     def debug(self): | ||||
|         """Run the tests without collecting errors in a TestResult""" | ||||
|         for test in self._tests: test.debug() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class FunctionTestCase(TestCase): | ||||
|     """A test case that wraps a test function. | ||||
| 
 | ||||
|  | @ -327,84 +369,100 @@ def shortDescription(self): | |||
| 
 | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Convenience functions | ||||
| # Locating and loading tests | ||||
| ############################################################################## | ||||
| 
 | ||||
| def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): | ||||
|     """Extracts all the names of functions in the given test case class | ||||
|        and its base classes that start with the given prefix. This is used | ||||
|        by makeSuite(). | ||||
| class TestLoader: | ||||
|     """This class is responsible for loading tests according to various | ||||
|     criteria and returning them wrapped in a Test | ||||
| 
 | ||||
|     It can load all tests within a given, module | ||||
|     """ | ||||
|     testFnNames = filter(lambda n,p=prefix: n[:len(p)] == p, | ||||
|     testMethodPrefix = 'test' | ||||
|     sortTestMethodsUsing = cmp | ||||
|     suiteClass = TestSuite | ||||
| 
 | ||||
|     def loadTestsFromTestCase(self, testCaseClass): | ||||
|         return self.suiteClass(map(testCaseClass, | ||||
|                                    self.getTestCaseNames(testCaseClass))) | ||||
| 
 | ||||
|     def loadTestsFromModule(self, module): | ||||
|         tests = [] | ||||
|         for name in dir(module): | ||||
|             obj = getattr(module, name) | ||||
|             if type(obj) == types.ClassType and issubclass(obj, TestCase): | ||||
|                 tests.append(self.loadTestsFromTestCase(obj)) | ||||
|         return self.suiteClass(tests) | ||||
| 
 | ||||
|     def loadTestsFromName(self, name, module=None): | ||||
|         parts = string.split(name, '.') | ||||
|         if module is None: | ||||
|             if not parts: | ||||
|                 raise ValueError, "incomplete test name: %s" % name | ||||
|             else: | ||||
|                 module = __import__(parts) | ||||
|                 parts = parts[1:] | ||||
|         obj = module | ||||
|         for part in parts: | ||||
|             obj = getattr(obj, part) | ||||
| 
 | ||||
|         if type(obj) == types.ModuleType: | ||||
|             return self.loadTestsFromModule(obj) | ||||
|         elif type(obj) == types.ClassType and issubclass(obj, TestCase): | ||||
|             return self.loadTestsFromTestCase(obj) | ||||
|         elif type(obj) == types.UnboundMethodType: | ||||
|             return obj.im_class(obj.__name__) | ||||
|         elif callable(obj): | ||||
|             test = obj() | ||||
|             if not isinstance(test, TestCase) and \ | ||||
|                not isinstance(test, TestSuite): | ||||
|                 raise ValueError, \ | ||||
|                       "calling %s returned %s, not a test" % obj,test | ||||
|             return test | ||||
|         else: | ||||
|             raise ValueError, "don't know how to make test from: %s" % obj | ||||
| 
 | ||||
|     def loadTestsFromNames(self, names, module=None): | ||||
|         suites = [] | ||||
|         for name in names: | ||||
|             suites.append(self.loadTestsFromName(name, module)) | ||||
|         return self.suiteClass(suites) | ||||
| 
 | ||||
|     def getTestCaseNames(self, testCaseClass): | ||||
|         testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p, | ||||
|                              dir(testCaseClass)) | ||||
|         for baseclass in testCaseClass.__bases__: | ||||
|         testFnNames = testFnNames + \ | ||||
|                       getTestCaseNames(baseclass, prefix, sortUsing=None) | ||||
|     if sortUsing: | ||||
|         testFnNames.sort(sortUsing) | ||||
|             for testFnName in self.getTestCaseNames(baseclass): | ||||
|                 if testFnName not in testFnNames:  # handle overridden methods | ||||
|                     testFnNames.append(testFnName) | ||||
|         if self.sortTestMethodsUsing: | ||||
|             testFnNames.sort(self.sortTestMethodsUsing) | ||||
|         return testFnNames | ||||
| 
 | ||||
| 
 | ||||
| def makeSuite(testCaseClass, prefix='test', sortUsing=cmp): | ||||
|     """Returns a TestSuite instance built from all of the test functions | ||||
|        in the given test case class whose names begin with the given | ||||
|        prefix. The cases are sorted by their function names | ||||
|        using the supplied comparison function, which defaults to 'cmp'. | ||||
|     """ | ||||
|     cases = map(testCaseClass, | ||||
|                 getTestCaseNames(testCaseClass, prefix, sortUsing)) | ||||
|     return TestSuite(cases) | ||||
| 
 | ||||
| defaultTestLoader = TestLoader() | ||||
| 
 | ||||
| 
 | ||||
| def createTestInstance(name, module=None): | ||||
|     """Finds tests by their name, optionally only within the given module. | ||||
| ############################################################################## | ||||
| # Patches for old functions: these functions should be considered obsolete | ||||
| ############################################################################## | ||||
| 
 | ||||
|     Return the newly-constructed test, ready to run. If the name contains a ':' | ||||
|     then the portion of the name after the colon is used to find a specific | ||||
|     test case within the test case class named before the colon. | ||||
| def _makeLoader(prefix, sortUsing, suiteClass=None): | ||||
|     loader = TestLoader() | ||||
|     loader.sortTestMethodsUsing = sortUsing | ||||
|     loader.testMethodPrefix = prefix | ||||
|     if suiteClass: loader.suiteClass = suiteClass | ||||
|     return loader | ||||
| 
 | ||||
|     Examples: | ||||
|      findTest('examples.listtests.suite') | ||||
|         -- returns result of calling 'suite' | ||||
|      findTest('examples.listtests.ListTestCase:checkAppend') | ||||
|         -- returns result of calling ListTestCase('checkAppend') | ||||
|      findTest('examples.listtests.ListTestCase:check-') | ||||
|         -- returns result of calling makeSuite(ListTestCase, prefix="check") | ||||
|     """ | ||||
| def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): | ||||
|     return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass) | ||||
| 
 | ||||
|     spec = string.split(name, ':') | ||||
|     if len(spec) > 2: raise ValueError, "illegal test name: %s" % name | ||||
|     if len(spec) == 1: | ||||
|         testName = spec[0] | ||||
|         caseName = None | ||||
|     else: | ||||
|         testName, caseName = spec | ||||
|     parts = string.split(testName, '.') | ||||
|     if module is None: | ||||
|         if len(parts) < 2: | ||||
|             raise ValueError, "incomplete test name: %s" % name | ||||
|         constructor = __import__(string.join(parts[:-1],'.')) | ||||
|         parts = parts[1:] | ||||
|     else: | ||||
|         constructor = module | ||||
|     for part in parts: | ||||
|         constructor = getattr(constructor, part) | ||||
|     if not callable(constructor): | ||||
|         raise ValueError, "%s is not a callable object" % constructor | ||||
|     if caseName: | ||||
|         if caseName[-1] == '-': | ||||
|             prefix = caseName[:-1] | ||||
|             if not prefix: | ||||
|                 raise ValueError, "prefix too short: %s" % name | ||||
|             test = makeSuite(constructor, prefix=prefix) | ||||
|         else: | ||||
|             test = constructor(caseName) | ||||
|     else: | ||||
|         test = constructor() | ||||
|     if not hasattr(test,"countTestCases"): | ||||
|         raise TypeError, \ | ||||
|               "object %s found with spec %s is not a test" % (test, name) | ||||
|     return test | ||||
| def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite): | ||||
|     return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass) | ||||
| 
 | ||||
| def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite): | ||||
|     return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module) | ||||
| 
 | ||||
| 
 | ||||
| ############################################################################## | ||||
|  | @ -415,181 +473,107 @@ class _WritelnDecorator: | |||
|     """Used to decorate file-like objects with a handy 'writeln' method""" | ||||
|     def __init__(self,stream): | ||||
|         self.stream = stream | ||||
|         if _isJPython: | ||||
|             import java.lang.System | ||||
|             self.linesep = java.lang.System.getProperty("line.separator") | ||||
|         else: | ||||
|             self.linesep = os.linesep | ||||
| 
 | ||||
|     def __getattr__(self, attr): | ||||
|         return getattr(self.stream,attr) | ||||
| 
 | ||||
|     def writeln(self, *args): | ||||
|         if args: apply(self.write, args) | ||||
|         self.write(self.linesep) | ||||
|         self.write('\n') # text-mode streams translate to \r\n if needed | ||||
|   | ||||
| 
 | ||||
| class _JUnitTextTestResult(TestResult): | ||||
| class _TextTestResult(TestResult): | ||||
|     """A test result class that can print formatted text results to a stream. | ||||
| 
 | ||||
|     Used by JUnitTextTestRunner. | ||||
|     Used by TextTestRunner. | ||||
|     """ | ||||
|     def __init__(self, stream): | ||||
|         self.stream = stream | ||||
|         TestResult.__init__(self) | ||||
|     separator1 = '=' * 70 | ||||
|     separator2 = '-' * 70 | ||||
| 
 | ||||
|     def addError(self, test, error): | ||||
|         TestResult.addError(self,test,error) | ||||
|         self.stream.write('E') | ||||
|         self.stream.flush() | ||||
|         if error[0] is KeyboardInterrupt: | ||||
|             self.shouldStop = 1 | ||||
|   | ||||
|     def addFailure(self, test, error): | ||||
|         TestResult.addFailure(self,test,error) | ||||
|         self.stream.write('F') | ||||
|         self.stream.flush() | ||||
|   | ||||
|     def startTest(self, test): | ||||
|         TestResult.startTest(self,test) | ||||
|         self.stream.write('.') | ||||
|         self.stream.flush() | ||||
| 
 | ||||
|     def printNumberedErrors(self,errFlavour,errors): | ||||
|         if not errors: return | ||||
|         if len(errors) == 1: | ||||
|             self.stream.writeln("There was 1 %s:" % errFlavour) | ||||
|         else: | ||||
|             self.stream.writeln("There were %i %ss:" % | ||||
|                                 (len(errors), errFlavour)) | ||||
|         i = 1 | ||||
|         for test,error in errors: | ||||
|             errString = string.join(apply(traceback.format_exception,error),"") | ||||
|             self.stream.writeln("%i) %s" % (i, test)) | ||||
|             self.stream.writeln(errString) | ||||
|             i = i + 1 | ||||
|   | ||||
|     def printErrors(self): | ||||
|         self.printNumberedErrors("error",self.errors) | ||||
| 
 | ||||
|     def printFailures(self): | ||||
|         self.printNumberedErrors("failure",self.failures) | ||||
| 
 | ||||
|     def printHeader(self): | ||||
|         self.stream.writeln() | ||||
|         if self.wasSuccessful(): | ||||
|             self.stream.writeln("OK (%i tests)" % self.testsRun) | ||||
|         else: | ||||
|             self.stream.writeln("!!!FAILURES!!!") | ||||
|             self.stream.writeln("Test Results") | ||||
|             self.stream.writeln() | ||||
|             self.stream.writeln("Run: %i ; Failures: %i ; Errors: %i" % | ||||
|                                 (self.testsRun, len(self.failures), | ||||
|                                  len(self.errors))) | ||||
|              | ||||
|     def printResult(self): | ||||
|         self.printHeader() | ||||
|         self.printErrors() | ||||
|         self.printFailures() | ||||
| 
 | ||||
| 
 | ||||
| class JUnitTextTestRunner: | ||||
|     """A test runner class that displays results in textual form. | ||||
|      | ||||
|     The display format approximates that of JUnit's 'textui' test runner. | ||||
|     This test runner may be removed in a future version of PyUnit. | ||||
|     """ | ||||
|     def __init__(self, stream=sys.stderr): | ||||
|         self.stream = _WritelnDecorator(stream) | ||||
| 
 | ||||
|     def run(self, test): | ||||
|         "Run the given test case or test suite." | ||||
|         result = _JUnitTextTestResult(self.stream) | ||||
|         startTime = time.time() | ||||
|         test(result) | ||||
|         stopTime = time.time() | ||||
|         self.stream.writeln() | ||||
|         self.stream.writeln("Time: %.3fs" % float(stopTime - startTime)) | ||||
|         result.printResult() | ||||
|         return result | ||||
| 
 | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Verbose text UI | ||||
| ############################################################################## | ||||
| 
 | ||||
| class _VerboseTextTestResult(TestResult): | ||||
|     """A test result class that can print formatted text results to a stream. | ||||
| 
 | ||||
|     Used by VerboseTextTestRunner. | ||||
|     """ | ||||
|     def __init__(self, stream, descriptions): | ||||
|     def __init__(self, stream, descriptions, verbosity): | ||||
|         TestResult.__init__(self) | ||||
|         self.stream = stream | ||||
|         self.lastFailure = None | ||||
|         self.showAll = verbosity > 1 | ||||
|         self.dots = verbosity == 1 | ||||
|         self.descriptions = descriptions | ||||
| 
 | ||||
|     def getDescription(self, test): | ||||
|         if self.descriptions: | ||||
|             return test.shortDescription() or str(test) | ||||
|         else: | ||||
|             return str(test) | ||||
| 
 | ||||
|     def startTest(self, test): | ||||
|         TestResult.startTest(self, test) | ||||
|         if self.descriptions: | ||||
|             self.stream.write(test.shortDescription() or str(test)) | ||||
|         else: | ||||
|             self.stream.write(str(test)) | ||||
|         if self.showAll: | ||||
|             self.stream.write(self.getDescription(test)) | ||||
|             self.stream.write(" ... ") | ||||
| 
 | ||||
|     def stopTest(self, test): | ||||
|         TestResult.stopTest(self, test) | ||||
|         if self.lastFailure is not test: | ||||
|     def addSuccess(self, test): | ||||
|         TestResult.addSuccess(self, test) | ||||
|         if self.showAll: | ||||
|             self.stream.writeln("ok") | ||||
|         elif self.dots: | ||||
|             self.stream.write('.') | ||||
| 
 | ||||
|     def addError(self, test, err): | ||||
|         TestResult.addError(self, test, err) | ||||
|         self._printError("ERROR", test, err) | ||||
|         self.lastFailure = test | ||||
|         if self.showAll: | ||||
|             self.stream.writeln("ERROR") | ||||
|         elif self.dots: | ||||
|             self.stream.write('E') | ||||
|         if err[0] is KeyboardInterrupt: | ||||
|             self.shouldStop = 1 | ||||
| 
 | ||||
|     def addFailure(self, test, err): | ||||
|         TestResult.addFailure(self, test, err) | ||||
|         self._printError("FAIL", test, err) | ||||
|         self.lastFailure = test | ||||
|         if self.showAll: | ||||
|             self.stream.writeln("FAIL") | ||||
|         elif self.dots: | ||||
|             self.stream.write('F') | ||||
| 
 | ||||
|     def _printError(self, flavour, test, err): | ||||
|         errLines = [] | ||||
|         separator1 = "\t" + '=' * 70 | ||||
|         separator2 = "\t" + '-' * 70 | ||||
|         if not self.lastFailure is test: | ||||
|     def printErrors(self): | ||||
|         if self.dots or self.showAll: | ||||
|             self.stream.writeln() | ||||
|             self.stream.writeln(separator1) | ||||
|         self.stream.writeln("\t%s" % flavour) | ||||
|         self.stream.writeln(separator2) | ||||
|         self.printErrorList('ERROR', self.errors) | ||||
|         self.printErrorList('FAIL', self.failures) | ||||
| 
 | ||||
|     def printErrorList(self, flavour, errors): | ||||
|         for test, err in errors: | ||||
|             self.stream.writeln(self.separator1) | ||||
|             self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) | ||||
|             self.stream.writeln(self.separator2) | ||||
|             for line in apply(traceback.format_exception, err): | ||||
|                 for l in string.split(line,"\n")[:-1]: | ||||
|                 self.stream.writeln("\t%s" % l) | ||||
|         self.stream.writeln(separator1) | ||||
|                     self.stream.writeln("%s" % l) | ||||
| 
 | ||||
| 
 | ||||
| class VerboseTextTestRunner: | ||||
| class TextTestRunner: | ||||
|     """A test runner class that displays results in textual form. | ||||
|      | ||||
|     It prints out the names of tests as they are run, errors as they | ||||
|     occur, and a summary of the results at the end of the test run. | ||||
|     """ | ||||
|     def __init__(self, stream=sys.stderr, descriptions=1): | ||||
|     def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1): | ||||
|         self.stream = _WritelnDecorator(stream) | ||||
|         self.descriptions = descriptions | ||||
|         self.verbosity = verbosity | ||||
| 
 | ||||
|     def _makeResult(self): | ||||
|         return _TextTestResult(self.stream, self.descriptions, self.verbosity) | ||||
| 
 | ||||
|     def run(self, test): | ||||
|         "Run the given test case or test suite." | ||||
|         result = _VerboseTextTestResult(self.stream, self.descriptions) | ||||
|         result = self._makeResult() | ||||
|         startTime = time.time() | ||||
|         test(result) | ||||
|         stopTime = time.time() | ||||
|         timeTaken = float(stopTime - startTime) | ||||
|         self.stream.writeln("-" * 78) | ||||
|         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)) | ||||
|                             (run, run == 1 and "" or "s", timeTaken)) | ||||
|         self.stream.writeln() | ||||
|         if not result.wasSuccessful(): | ||||
|             self.stream.write("FAILED (") | ||||
|  | @ -605,9 +589,6 @@ def run(self, test): | |||
|         return result | ||||
|          | ||||
| 
 | ||||
| # Which flavour of TextTestRunner is the default? | ||||
| TextTestRunner = VerboseTextTestRunner | ||||
| 
 | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Facilities for running tests from the command line | ||||
|  | @ -618,17 +599,22 @@ class TestProgram: | |||
|        for making test modules conveniently executable. | ||||
|     """ | ||||
|     USAGE = """\ | ||||
| Usage: %(progName)s [-h|--help] [test[:(casename|prefix-)]] [...] | ||||
| Usage: %(progName)s [options] [test[:(casename|prefix-)]] [...] | ||||
| 
 | ||||
| Options: | ||||
|   -h, --help       Show this message | ||||
|   -v, --verbose    Verbose output | ||||
|   -q, --quiet      Minimal output | ||||
| 
 | ||||
| Examples: | ||||
|   %(progName)s                               - run default set of tests | ||||
|   %(progName)s MyTestSuite                   - run suite 'MyTestSuite' | ||||
|   %(progName)s MyTestCase:checkSomething     - run MyTestCase.checkSomething | ||||
|   %(progName)s MyTestCase:check-             - run all 'check*' test methods | ||||
|   %(progName)s MyTestCase.testSomething      - run MyTestCase.testSomething | ||||
|   %(progName)s MyTestCase                    - run all 'test*' test methods | ||||
|                                                in MyTestCase | ||||
| """ | ||||
|     def __init__(self, module='__main__', defaultTest=None, | ||||
|                  argv=None, testRunner=None): | ||||
|                  argv=None, testRunner=None, testLoader=defaultTestLoader): | ||||
|         if type(module) == type(''): | ||||
|             self.module = __import__(module) | ||||
|             for part in string.split(module,'.')[1:]: | ||||
|  | @ -637,11 +623,12 @@ def __init__(self, module='__main__', defaultTest=None, | |||
|             self.module = module | ||||
|         if argv is None: | ||||
|             argv = sys.argv | ||||
|         self.verbosity = 1 | ||||
|         self.defaultTest = defaultTest | ||||
|         self.testRunner = testRunner | ||||
|         self.testLoader = testLoader | ||||
|         self.progName = os.path.basename(argv[0]) | ||||
|         self.parseArgs(argv) | ||||
|         self.createTests() | ||||
|         self.runTests() | ||||
| 
 | ||||
|     def usageExit(self, msg=None): | ||||
|  | @ -652,29 +639,34 @@ def usageExit(self, msg=None): | |||
|     def parseArgs(self, argv): | ||||
|         import getopt | ||||
|         try: | ||||
|             options, args = getopt.getopt(argv[1:], 'hH', ['help']) | ||||
|             options, args = getopt.getopt(argv[1:], 'hHvq', | ||||
|                                           ['help','verbose','quiet']) | ||||
|             opts = {} | ||||
|             for opt, value in options: | ||||
|                 if opt in ('-h','-H','--help'): | ||||
|                     self.usageExit() | ||||
|                 if opt in ('-q','--quiet'): | ||||
|                     self.verbosity = 0 | ||||
|                 if opt in ('-v','--verbose'): | ||||
|                     self.verbosity = 2 | ||||
|             if len(args) == 0 and self.defaultTest is None: | ||||
|                 raise getopt.error, "No default test is defined." | ||||
|                 self.test = self.testLoader.loadTestsFromModule(self.module) | ||||
|                 return | ||||
|             if len(args) > 0: | ||||
|                 self.testNames = args | ||||
|             else: | ||||
|                 self.testNames = (self.defaultTest,) | ||||
|             self.createTests() | ||||
|         except getopt.error, msg: | ||||
|             self.usageExit(msg) | ||||
| 
 | ||||
|     def createTests(self): | ||||
|         tests = [] | ||||
|         for testName in self.testNames: | ||||
|             tests.append(createTestInstance(testName, self.module)) | ||||
|         self.test = TestSuite(tests) | ||||
|         self.test = self.testLoader.loadTestsFromNames(self.testNames, | ||||
|                                                        self.module) | ||||
| 
 | ||||
|     def runTests(self): | ||||
|         if self.testRunner is None: | ||||
|             self.testRunner = TextTestRunner() | ||||
|             self.testRunner = TextTestRunner(verbosity=self.verbosity) | ||||
|         result = self.testRunner.run(self.test) | ||||
|         sys.exit(not result.wasSuccessful())     | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Steve Purcell
						Steve Purcell