[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