[Zope-Checkins] CVS: Zope/utilities - testrunner.py:1.19.14.1

Tres Seaver tseaver@zope.com
Sun, 18 Nov 2001 23:20:59 -0500


Update of /cvs-repository/Zope/utilities
In directory cvs.zope.org:/tmp/cvs-serv31428/utilities

Modified Files:
      Tag: tseaver-utxr-refactoring-branch
	testrunner.py 
Log Message:


 - Moved utilitiy functions for finding tests out into an importable
   module, so that they can be run directly by an alternate runner
   (e.g., the Tkinter-based 'unittestgui'). For instance, from the
   top of the Zope tree, the following now works::

    $ PYTHONPATH=./lib/python:. python2.1 \
        /usr/local/lib/python2.1/unittestgui.py Testing.Builder.allZopeTests

   It produces a GUI which does the classic "red-bar/green-bar"
   feedback cycle.
   
   'unittestgui.py' is available at:

     http://pyunit.sourceforge.net

 - Reactored test-finding using 'os.path.walk' and the standard
   'loadTestsFromName' provided by 'unittest';  this will allow,
   for instance, creation of unit test modules without the stupid
   'def test_suite' boilerplate.

   TODO:  update 'utilities/testrunner' to use the refactored finder.


=== Zope/utilities/testrunner.py 1.19 => 1.19.14.1 ===
 VERBOSE = 2
 
+
 class TestRunner:
     """Test suite runner"""
 
@@ -46,39 +47,6 @@
             sys.path.insert(0, pjoin(path, 'lib/python'))
             sys.path.insert(1, path)
 
-    def getSuiteFromFile(self, filepath):
-        if not os.path.isfile(filepath):
-            raise ValueError, '%s is not a file' % filepath
-        path, filename=os.path.split(filepath)
-        name, ext=os.path.splitext(filename)
-        file, pathname, desc=imp.find_module(name, [path])
-        saved_syspath = sys.path[:]
-        try:
-            module=imp.load_module(name, file, pathname, desc)
-        finally:
-            file.close()
-            sys.path[:] = saved_syspath
-        function=getattr(module, 'test_suite', None)
-        if function is None:
-            return None
-        return function()
-
-    def smellsLikeATest(self, filepath, find=string.find):
-        path, name = os.path.split(filepath)
-        fname, ext = os.path.splitext(name)
-        
-        if name[:4]=='test' and name[-3:]=='.py' and \
-           name != 'testrunner.py':
-            
-            file=open(filepath, 'r')
-            lines=file.readlines()
-            file.close()
-            for line in lines:
-                if (find(line, 'def test_suite(') > -1) or \
-                   (find(line, 'framework(') > -1):
-                    return 1
-        return 0
-
     def runSuite(self, suite):
         runner=unittest.TextTestRunner(verbosity=self.verbosity)
         self.results.append(runner.run(suite))
@@ -88,81 +56,47 @@
 
     def runAllTests(self):
         """Run all tests found in the current working directory and
-           all subdirectories."""
-        self.runPath(self.basepath)
-
-    def listTestableNames( self, pathname ):
-        """
-            Return a list of the names to be traversed to build tests.
+           all subdirectories.
         """
-        names = os.listdir(pathname)
-        if '.testinfo' in names:  # allow local control
-            f = open( os.path.join( pathname, '.testinfo' ) )
-            lines = filter( None, f.readlines() )
-            lines = map( lambda x: x[-1]=='\n' and x[:-1] or x, lines )
-            names = filter( lambda x: x and x[0] != '#', lines )
-            f.close()
-        return names
+        self.runPath( self.basepath )
 
-    def extractSuite( self, pathname ):
-        """
-            Extract and return the appropriate test suite.
-        """
-        if os.path.isdir( pathname ):
-
-            suite = unittest.TestSuite()
 
-            for name in self.listTestableNames( pathname ):
+    def runPath(self, pathname):
+        """Run all tests found in the directory named by pathname
+           and all subdirectories.
+        """
+        from Testing.Builder import smellsLikeATest
+        from Testing.Builder import listTestableNames
+        from Testing.Builder import extractSuite
 
-                fullpath = os.path.join( pathname, name )
-                sub_suite = self.extractSuite( fullpath )
-                if sub_suite:
-                    suite.addTest( sub_suite )
-
-            return suite.countTestCases() and suite or None
-
-        elif self.smellsLikeATest( pathname ):
-
-            working_dir = os.getcwd()
-            try:
-                dirname, name = os.path.split(pathname)
-                if dirname:
-                    os.chdir(dirname)
-                try:
-                    suite = self.getSuiteFromFile(name)
-                except:
-                    self.report('No test suite found in file:\n%s\n' % pathname)
-                    if self.verbosity > 1:
-                        traceback.print_exc()
-                    suite = None            
-            finally:
-                os.chdir(working_dir)
-            
-            return suite
+        if not os.path.isabs( pathname ):
+            pathname = os.path.join( self.basepath, pathname )
 
-        else: # no test there!
+        if self.mega_suite:
 
-            return None
+            suite, import_failures = extractSuite( pathname )
 
-    def runPath(self, pathname):
-        """Run all tests found in the directory named by pathname
-           and all subdirectories."""
-        if not os.path.isabs(pathname):
-            pathname = os.path.join(self.basepath, pathname)
+            for imp_failed in import_failures:
+                self.report( 'No test suite found in file: %s' % imp_failed )
 
-        if self.mega_suite:
-            suite = self.extractSuite( pathname )
             self.runSuite( suite )
+
         else:
-            for name in self.listTestableNames(pathname):
+
+            for name in listTestableNames( pathname ):
+
                 fullpath=os.path.join(pathname, name)
-                if os.path.isdir(fullpath):
-                    self.runPath(fullpath)
-                elif self.smellsLikeATest(fullpath):
-                    self.runFile(fullpath)
+
+                if os.path.isdir( fullpath ):
+                    self.runPath( fullpath )
+
+                elif smellsLikeATest( fullpath ):
+                    self.runFile( fullpath )
 
     def runFile(self, filename):
-        """Run the test suite defined by filename."""
+        """Run the test suite defined by filename.
+        """
+        from Testing.Builder import getSuiteFromFile
         working_dir = os.getcwd()
         dirname, name = os.path.split(filename)
         if dirname:
@@ -170,7 +104,8 @@
                 sys.stderr.write( '*** Changing directory to: %s\n' % dirname )
             os.chdir(dirname)
         self.report('Running: %s' % filename)
-        try:    suite=self.getSuiteFromFile(name)
+        try:
+            suite = getSuiteFromFile( name )
         except:
             traceback.print_exc()
             suite=None            
@@ -185,7 +120,9 @@
 
 def main(args):
 
-    usage_msg="""Usage: python testrunner.py options
+    usage_msg="""\
+    
+    Usage: python testrunner.py options
 
     If run without options, testrunner will display this usage
     message. If you want to run all test suites found in all