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

Tres Seaver tseaver@zope.com
Mon, 15 Oct 2001 19:15:55 -0400


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

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


 o Add new command line options:

       -m 

          Run all tests in a single, giant suite (consolidates error
          reporting).  This makes running the tests much cleaner, and
          more "PyUnit"-like.

       -P

          *Don't* add 'lib/python' to the Python search path (on
          by default).

 o *Stop* munging sys.path to make "local imports" work (source of
   ugly side effect bugs).


=== Zope/utilities/testrunner.py 1.15.20.2 => 1.15.20.3 ===
     """Test suite runner"""
 
-    def __init__(self, basepath, verbosity=VERBOSE, results=[]):
+    def __init__(self, basepath, verbosity=VERBOSE, results=[], mega_suite=0):
         # initialize python path
         self.basepath=path=basepath
         self.verbosity = verbosity
         self.results = results
+        self.mega_suite = mega_suite
         pjoin=os.path.join
         if sys.platform == 'win32':
             sys.path.insert(0, pjoin(path, 'lib/python'))
@@ -51,12 +52,10 @@
         path, filename=os.path.split(filepath)
         name, ext=os.path.splitext(filename)
         file, pathname, desc=imp.find_module(name, [path])
-        # Add path of imported module to sys.path, so local imports work.
-        sys.path.insert(0, path)
-        try:     module=imp.load_module(name, file, pathname, desc)
-        finally: file.close()
-        # Remove extra path again.
-        sys.path.remove(path)
+        try:
+            module=imp.load_module(name, file, pathname, desc)
+        finally:
+            file.close()
         function=getattr(module, 'test_suite', None)
         if function is None:
             return None
@@ -90,24 +89,75 @@
            all subdirectories."""
         self.runPath(self.basepath)
 
-    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)
-        names=os.listdir(pathname)
+    def listTestableNames( self, pathname ):
+        """
+            Return a list of the names to be traversed to build tests.
+        """
+        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()
-        for name in names:
-            fullpath=os.path.join(pathname, name)
-            if os.path.isdir(fullpath):
-                self.runPath(fullpath)
-            elif self.smellsLikeATest(fullpath):
-                self.runFile(fullpath)
+        return names
+
+    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 ):
+
+                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
+
+        else: # no test there!
+
+            return None
+
+    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)
+
+        if self.mega_suite:
+            suite = self.extractSuite( pathname )
+            self.runSuite( suite )
+        else:
+            for name in self.listTestableNames(pathname):
+                fullpath=os.path.join(pathname, name)
+                if os.path.isdir(fullpath):
+                    self.runPath(fullpath)
+                elif self.smellsLikeATest(fullpath):
+                    self.runFile(fullpath)
 
     def runFile(self, filename):
         """Run the test suite defined by filename."""
@@ -148,6 +198,16 @@
           working directory. This is the default if no options are
           specified.
 
+       -m 
+
+          Run all tests in a single, giant suite (consolidates error
+          reporting).
+
+       -P
+
+          *Don't* add 'lib/python' to the Python search path (on
+          by default).
+
        -d dirpath
 
           Run all tests found in the directory specified by dirpath,
@@ -186,14 +246,20 @@
     filename=None
     test_all=None
     verbosity = VERBOSE
+    mega_suite = 0
+    set_python_path = 1
 
-    options, arg=getopt.getopt(args, 'ahd:f:v:q')
+    options, arg=getopt.getopt(args, 'amPhd:f:v:q')
     if not options:
         err_exit(usage_msg)
     for name, value in options:
         name=name[1:]
         if name == 'a':
             test_all=1
+        elif name == 'm':
+            mega_suite = 1
+        elif name == 'P':
+            set_python_path = 0
         elif name == 'd':
             pathname=string.strip(value)
         elif name == 'f':
@@ -207,7 +273,14 @@
         else:
             err_exit(usage_msg)
 
-    testrunner = TestRunner(os.getcwd(), verbosity=verbosity)
+    testrunner = TestRunner( os.getcwd()
+                           , verbosity=verbosity
+                           , mega_suite=mega_suite)
+
+    if set_python_path:
+        testrunner.report( "Adding %s/lib/python to sys.path." % os.getcwd() )
+        sys.path.insert( 0, os.path.join( os.getcwd(), 'lib/python' ) )
+
     if test_all:
         testrunner.runAllTests()
     elif pathname: