[Zope3-checkins]
SVN: zope.testing/branches/colorized-output/src/zope/testing/testrunner
Make the output with -c exactly match the output without -c
(modulo the colors,
Marius Gedminas
marius at pov.lt
Sat Jul 14 12:35:10 EDT 2007
Log message for revision 77950:
Make the output with -c exactly match the output without -c (modulo the colors,
of course). Add a test for colorizing the output.
Changed:
A zope.testing/branches/colorized-output/src/zope/testing/testrunner-colors.txt
U zope.testing/branches/colorized-output/src/zope/testing/testrunner.py
-=-
Added: zope.testing/branches/colorized-output/src/zope/testing/testrunner-colors.txt
===================================================================
--- zope.testing/branches/colorized-output/src/zope/testing/testrunner-colors.txt (rev 0)
+++ zope.testing/branches/colorized-output/src/zope/testing/testrunner-colors.txt 2007-07-14 16:35:09 UTC (rev 77950)
@@ -0,0 +1,172 @@
+Colorful output
+===============
+
+If you're on a Unix-like system, you can ask for colorized output. The test
+runner emits terminal control sequences to highlight important pieces of
+information (such as the names of failing tests) in different colors.
+
+ >>> import os.path, sys
+ >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+ >>> defaults = [
+ ... '--path', directory_with_tests,
+ ... '--tests-pattern', '^sampletestsf?$',
+ ... ]
+
+ >>> from zope.testing import testrunner
+
+Since it wouldn't be a good idea to have terminal control characters in a
+test file, let's wrap sys.stdout in a simple terminal interpreter
+
+ >>> import re
+ >>> class Terminal(object):
+ ... _color_regexp = re.compile('\033[[]([0-9;]*)m')
+ ... _colors = {'0': 'normal', '1': 'bold', '30': 'black', '31': 'red',
+ ... '32': 'green', '33': 'yellow', '34': 'blue',
+ ... '35': 'magenta', '36': 'cyan', '37': 'grey'}
+ ... def __init__(self, stream):
+ ... self._stream = stream
+ ... def __getattr__(self, attr):
+ ... return getattr(self._stream, attr)
+ ... def write(self, text):
+ ... if '\033[' in text:
+ ... text = self._color_regexp.sub(self._color, text)
+ ... self._stream.write(text)
+ ... def writelines(self, lines):
+ ... for line in lines:
+ ... self.write(line)
+ ... def _color(self, match):
+ ... colorstring = '{'
+ ... for number in match.group(1).split(';'):
+ ... colorstring += self._colors.get(number, '?')
+ ... return colorstring + '}'
+
+ >>> real_stdout = sys.stdout
+ >>> sys.stdout = Terminal(sys.stdout)
+
+A successful test run soothes the developer with warm green colors:
+
+ >>> sys.argv = 'test --layer 122 -c'.split()
+ >>> testrunner.run(defaults)
+ {normal}Running samplelayers.Layer122 tests:{normal}
+ Set up samplelayers.Layer1 in 0.000 seconds.
+ Set up samplelayers.Layer12 in 0.000 seconds.
+ Set up samplelayers.Layer122 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.007{normal} seconds.{normal}
+ {normal}Tearing down left over layers:{normal}
+ Tear down samplelayers.Layer122 in 0.000 seconds.
+ Tear down samplelayers.Layer12 in 0.000 seconds.
+ Tear down samplelayers.Layer1 in 0.000 seconds.
+ False
+
+A failed test run highlights the failures in red:
+
+ >>> sys.argv = 'test -c --tests-pattern ^sampletests(f|_e|_f)?$ '.split()
+ >>> testrunner.run(defaults)
+ {normal}Running unit tests:{normal}
+ <BLANKLINE>
+ <BLANKLINE>
+ {boldred}Failure in test eek (sample2.sampletests_e){normal}
+ Failed doctest test for sample2.sampletests_e.eek
+ File "testrunner-ex/sample2/sampletests_e.py", line 28, in eek
+ <BLANKLINE>
+ ----------------------------------------------------------------------
+ {normal}File "{boldblue}testrunner-ex/sample2/sampletests_e.py{normal}", line {boldred}30{normal}, in {boldcyan}sample2.sampletests_e.eek{normal}
+ Failed example:
+ {cyan} f(){normal}
+ Exception raised:
+ {red} Traceback (most recent call last):{normal}
+ {red} File ".../doctest.py", line 1356, in __run{normal}
+ {red} compileflags, 1) in test.globs{normal}
+ {red} File "<doctest sample2.sampletests_e.eek[0]>", line 1, in ?{normal}
+ {red} f(){normal}
+ {red} File "testrunner-ex/sample2/sampletests_e.py", line 19, in f{normal}
+ {red} g(){normal}
+ {red} File "testrunner-ex/sample2/sampletests_e.py", line 24, in g{normal}
+ {red} x = y + 1{normal}
+ {red} NameError: global name 'y' is not defined{normal}
+ <BLANKLINE>
+ <BLANKLINE>
+ <BLANKLINE>
+ {boldred}Error in test test3 (sample2.sampletests_e.Test){normal}
+ Traceback (most recent call last):
+ {normal} File "{boldblue}unittest.py{normal}", line {boldred}260{normal}, in {boldcyan}run{normal}
+ {cyan} testMethod(){normal}
+ {normal} File "{boldblue}testrunner-ex/sample2/sampletests_e.py{normal}", line {boldred}43{normal}, in {boldcyan}test3{normal}
+ {cyan} f(){normal}
+ {normal} File "{boldblue}testrunner-ex/sample2/sampletests_e.py{normal}", line {boldred}19{normal}, in {boldcyan}f{normal}
+ {cyan} g(){normal}
+ {normal} File "{boldblue}testrunner-ex/sample2/sampletests_e.py{normal}", line {boldred}24{normal}, in {boldcyan}g{normal}
+ {cyan} x = y + 1{normal}
+ {red}NameError: global name 'y' is not defined{normal}
+ <BLANKLINE>
+ <BLANKLINE>
+ <BLANKLINE>
+ {boldred}Failure in test testrunner-ex/sample2/e.txt{normal}
+ Failed doctest test for e.txt
+ File "testrunner-ex/sample2/e.txt", line 0
+ <BLANKLINE>
+ ----------------------------------------------------------------------
+ {normal}File "{boldblue}testrunner-ex/sample2/e.txt{normal}", line {boldred}4{normal}, in {boldcyan}e.txt{normal}
+ Failed example:
+ {cyan} f(){normal}
+ Exception raised:
+ {red} Traceback (most recent call last):{normal}
+ {red} File ".../doctest.py", line 1356, in __run{normal}
+ {red} compileflags, 1) in test.globs{normal}
+ {red} File "<doctest e.txt[1]>", line 1, in ?{normal}
+ {red} f(){normal}
+ {red} File "<doctest e.txt[0]>", line 2, in f{normal}
+ {red} return x{normal}
+ {red} NameError: global name 'x' is not defined{normal}
+ <BLANKLINE>
+ <BLANKLINE>
+ <BLANKLINE>
+ {boldred}Failure in test test (sample2.sampletests_f.Test){normal}
+ Traceback (most recent call last):
+ {normal} File "{boldblue}unittest.py{normal}", line {boldred}260{normal}, in {boldcyan}run{normal}
+ {cyan} testMethod(){normal}
+ {normal} File "{boldblue}testrunner-ex/sample2/sampletests_f.py{normal}", line {boldred}21{normal}, in {boldcyan}test{normal}
+ {cyan} self.assertEqual(1,0){normal}
+ {normal} File "{boldblue}unittest.py{normal}", line {boldred}333{normal}, in {boldcyan}failUnlessEqual{normal}
+ {cyan} raise self.failureException, \{normal}
+ {red}AssertionError: 1 != 0{normal}
+ <BLANKLINE>
+ {normal} Ran {green}200{normal} tests with {boldred}3{normal} failures and {boldred}1{normal} errors in {green}0.045{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer1 tests:{normal}
+ Set up samplelayers.Layer1 in 0.000 seconds.
+ {normal} Ran {green}9{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.001{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer11 tests:{normal}
+ Set up samplelayers.Layer11 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.007{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer111 tests:{normal}
+ Set up samplelayers.Layerx in 0.000 seconds.
+ Set up samplelayers.Layer111 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.008{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer112 tests:{normal}
+ Tear down samplelayers.Layer111 in 0.000 seconds.
+ Set up samplelayers.Layer112 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.008{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer12 tests:{normal}
+ Tear down samplelayers.Layer112 in 0.000 seconds.
+ Tear down samplelayers.Layerx in 0.000 seconds.
+ Tear down samplelayers.Layer11 in 0.000 seconds.
+ Set up samplelayers.Layer12 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.007{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer121 tests:{normal}
+ Set up samplelayers.Layer121 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.007{normal} seconds.{normal}
+ {normal}Running samplelayers.Layer122 tests:{normal}
+ Tear down samplelayers.Layer121 in 0.000 seconds.
+ Set up samplelayers.Layer122 in 0.000 seconds.
+ {normal} Ran {green}34{normal} tests with {green}0{normal} failures and {green}0{normal} errors in {green}0.008{normal} seconds.{normal}
+ {normal}Tearing down left over layers:{normal}
+ Tear down samplelayers.Layer122 in 0.000 seconds.
+ Tear down samplelayers.Layer12 in 0.000 seconds.
+ Tear down samplelayers.Layer1 in 0.000 seconds.
+ {normal}Total: {green}413{normal} tests, {boldred}3{normal} failures, {boldred}1{normal} errors{normal}
+ True
+
+Clean up:
+
+ >>> sys.stdout = real_stdout
+
Property changes on: zope.testing/branches/colorized-output/src/zope/testing/testrunner-colors.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.testing/branches/colorized-output/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/branches/colorized-output/src/zope/testing/testrunner.py 2007-07-14 16:31:51 UTC (rev 77949)
+++ zope.testing/branches/colorized-output/src/zope/testing/testrunner.py 2007-07-14 16:35:09 UTC (rev 77950)
@@ -679,9 +679,9 @@
sys.stdout.writelines([
self.color('info'), 'Total: ',
self.color('number'), str(n_tests),
- self.color('info'), ' tests with ',
+ self.color('info'), ' tests, ',
self.error_count_color(n_failures), str(n_failures),
- self.color('info'), ' failures and ',
+ self.color('info'), ' failures, ',
self.error_count_color(n_errors), str(n_errors),
self.color('info'), ' errors',
self.color('normal'), '\n'])
@@ -746,6 +746,7 @@
else:
color_of_indented_text = 'normal'
print line
+ print
def print_colorized_traceback(self, formatted_traceback):
"""Report a test failure.
@@ -773,6 +774,7 @@
print line
else:
print self.colorize('exception', line)
+ print
def run(defaults=None, args=None):
@@ -2424,6 +2426,7 @@
(re.compile(r'\r'), '\\\\r\n'),
(re.compile(r'\d+[.]\d\d\d seconds'), 'N.NNN seconds'),
(re.compile(r'\d+[.]\d\d\d s'), 'N.NNN s'),
+ (re.compile(r'\d+[.]\d\d\d{'), 'N.NNN{'),
(re.compile('( |")[^\n]+testrunner-ex'), r'\1testrunner-ex'),
(re.compile('( |")[^\n]+testrunner.py'), r'\1testrunner.py'),
(re.compile(r'> [^\n]*(doc|unit)test[.]py\(\d+\)'),
@@ -2468,6 +2471,7 @@
'testrunner-layers.txt',
'testrunner-layers-api.txt',
'testrunner-progress.txt',
+ 'testrunner-colors.txt',
'testrunner-simple.txt',
'testrunner-test-selection.txt',
'testrunner-verbose.txt',
More information about the Zope3-Checkins
mailing list