[Zope-Checkins] CVS: Zope/utilities - testrunner.py:1.36
Fred L. Drake, Jr.
fred@zope.com
Fri, 21 Mar 2003 15:22:31 -0500
Update of /cvs-repository/Zope/utilities
In directory cvs.zope.org:/tmp/cvs-serv13525
Modified Files:
testrunner.py
Log Message:
New command-line option: -e tells testrunner.py to print a line with
information on tests that fail, regardless of the verbosity setting.
This allows using -v0 or -v1, and still seeing useful error
information as the tests are run. This is especially helpful for
large or long-running test suites.
=== Zope/utilities/testrunner.py 1.35 => 1.36 ===
--- Zope/utilities/testrunner.py:1.35 Fri Jan 31 10:46:42 2003
+++ Zope/utilities/testrunner.py Fri Mar 21 15:22:30 2003
@@ -33,9 +33,10 @@
class TestRunner:
"""Test suite runner"""
- def __init__(self, path, verbosity, mega_suite):
+ def __init__(self, path, verbosity, mega_suite, verbose_on_error):
self.basepath = path
self.verbosity = verbosity
+ self.verbose_on_error = verbose_on_error
self.results = []
self.mega_suite = mega_suite
# initialize python path
@@ -112,8 +113,9 @@
return self._runner
def createTestRunner(self):
- return unittest.TextTestRunner(stream=sys.stderr,
- verbosity=self.verbosity)
+ return FancyTestRunner(stream=sys.stderr,
+ verbosity=self.verbosity,
+ verbose_on_error=self.verbose_on_error)
def report(self, message):
print >>sys.stderr, message
@@ -214,13 +216,82 @@
os.chdir(working_dir)
-class TimingTestResult(unittest._TextTestResult):
+class FancyTestResult(unittest._TextTestResult):
+ have_blank_line = 1
+ verbose_on_error = 0
+
def __init__(self, *args, **kw):
- self.timings = []
+ if "verbose_on_error" in kw:
+ self.verbose_on_error = kw["verbose_on_error"]
+ del kw["verbose_on_error"]
unittest._TextTestResult.__init__(self, *args, **kw)
+ def addSuccess(self, test):
+ unittest.TestResult.addSuccess(self, test)
+ if self.showAll:
+ self.stream.writeln("ok")
+ elif self.dots:
+ self.stream.write('.')
+ self.have_blank_line = 0
+
+ def addError(self, test, err):
+ unittest.TestResult.addError(self, test, err)
+ if self.showAll:
+ self.stream.writeln(excname(err[0]))
+ elif self.verbose_on_error:
+ if not self.have_blank_line:
+ self.stream.writeln()
+ self.stream.write(self.getDescription(test) + ": ")
+ if isinstance(err[0], str):
+ self.stream.writeln(err[0])
+ else:
+ self.stream.writeln(excname(err[0]))
+ self.have_blank_line = 1
+ elif self.dots:
+ self.stream.write("E")
+ self.have_blank_line = 0
+
+ def addFailure(self, test, err):
+ unittest.TestResult.addFailure(self, test, err)
+ if self.showAll:
+ self.stream.writeln("FAIL")
+ elif self.verbose_on_error:
+ if not self.have_blank_line:
+ self.stream.writeln()
+ self.stream.writeln(self.getDescription(test) + ": FAIL")
+ self.have_blank_line = 1
+ elif self.dots:
+ self.stream.write("F")
+ self.have_blank_line = 0
+
+def excname(cls):
+ if cls.__module__ == "exceptions":
+ return cls.__name__
+ else:
+ return "%s.%s" % (cls.__module__, cls.__name__)
+
+
+class FancyTestRunner(unittest.TextTestRunner):
+ def __init__(self, *args, **kw):
+ if "verbose_on_error" in kw:
+ self.verbose_on_error = kw["verbose_on_error"]
+ del kw["verbose_on_error"]
+ else:
+ self.verbose_on_error = False
+ unittest.TextTestRunner.__init__(self, *args, **kw)
+
+ def _makeResult(self):
+ return FancyTestResult(self.stream, self.descriptions, self.verbosity,
+ verbose_on_error=self.verbose_on_error)
+
+
+class TimingTestResult(FancyTestResult):
+ def __init__(self, *args, **kw):
+ self.timings = []
+ FancyTestResult.__init__(self, *args, **kw)
+
def startTest(self, test):
- unittest._TextTestResult.startTest(self, test)
+ FancyTestResult.startTest(self, test)
self._t2 = None
self._t1 = time.time()
@@ -230,28 +301,29 @@
t2 = self._t2
t = t2 - self._t1
self.timings.append((t, str(test)))
- unittest._TextTestResult.stopTest(self, test)
+ FancyTestResult.stopTest(self, test)
def addSuccess(self, test):
self._t2 = time.time()
- unittest._TextTestResult.addSuccess(self, test)
+ FancyTestResult.addSuccess(self, test)
def addError(self, test, err):
self._t2 = time.time()
- unittest._TextTestResult.addError(self, test, err)
+ FancyTestResult.addError(self, test, err)
def addFailure(self, test, err):
self._t2 = time.time()
- unittest._TextTestResult.addFailure(self, test, err)
+ FancyTestResult.addFailure(self, test, err)
-class TimingTestRunner(unittest.TextTestRunner):
+class TimingTestRunner(FancyTestRunner):
def __init__(self, *args, **kw):
- unittest.TextTestRunner.__init__(self, *args, **kw)
+ FancyTestRunner.__init__(self, *args, **kw)
self.timings = []
def _makeResult(self):
- r = TimingTestResult(self.stream, self.descriptions, self.verbosity)
+ r = TimingTestResult(self.stream, self.descriptions, self.verbosity,
+ verbose_on_error=self.verbose_on_error)
self.timings = r.timings
return r
@@ -259,7 +331,8 @@
class TestTimer(TestRunner):
def createTestRunner(self):
return TimingTestRunner(stream=sys.stderr,
- verbosity=self.verbosity)
+ verbosity=self.verbosity,
+ verbose_on_error=self.verbose_on_error)
def reportTimes(self, num):
r = self.getTestRunner()
@@ -324,6 +397,13 @@
1 - Quiet (produces a dot for each succesful test)
2 - Verbose (default - produces a line of output for each test)
+ -e
+ Modifier to the verbosity level. This causes a errors and
+ failures to generate a one-line report the test instead of
+ an 'E' or 'F'. This can make it easier to work on solving
+ problem while the tests are still running. This causes the
+ 'silent' mode (-v0) to be less than completely silent.
+
-q
Run tests without producing verbose output. The tests are
normally run in verbose mode, which produces a line of
@@ -349,8 +429,9 @@
mega_suite = True
set_python_path = True
timed = 0
+ verbose_on_error = False
- options, arg = getopt.getopt(args, 'amPhd:f:v:qMo:t:')
+ options, arg = getopt.getopt(args, 'aemPhd:f:v:qMo:t:')
if not options:
err_exit(usage_msg)
for name, value in options:
@@ -370,6 +451,8 @@
filename = value.strip()
elif name == '-h':
err_exit(usage_msg, 0)
+ elif name == '-e':
+ verbose_on_error = True
elif name == '-v':
verbosity = int(value)
elif name == '-q':
@@ -386,9 +469,11 @@
os.path.walk(os.curdir, remove_stale_bytecode, None)
if timed:
- testrunner = TestTimer(os.getcwd(), verbosity, mega_suite)
+ testrunner = TestTimer(os.getcwd(), verbosity, mega_suite,
+ verbose_on_error)
else:
- testrunner = TestRunner(os.getcwd(), verbosity, mega_suite)
+ testrunner = TestRunner(os.getcwd(), verbosity, mega_suite,
+ verbose_on_error)
if set_python_path:
script = sys.argv[0]