[Zope3-checkins] SVN: zope.testing/trunk/src/zope/testing/testrunner/ added missing test for post mortem debugging in StartUpFailure
Michael Howitz
mh at gocept.com
Wed Aug 13 04:21:59 EDT 2008
Log message for revision 89786:
added missing test for post mortem debugging in StartUpFailure
Changed:
A zope.testing/trunk/src/zope/testing/testrunner/debug.py
U zope.testing/trunk/src/zope/testing/testrunner/find.py
U zope.testing/trunk/src/zope/testing/testrunner/interfaces.py
U zope.testing/trunk/src/zope/testing/testrunner/runner.py
U zope.testing/trunk/src/zope/testing/testrunner/tests.py
-=-
Copied: zope.testing/trunk/src/zope/testing/testrunner/debug.py (from rev 89785, zope.testing/trunk/src/zope/testing/testrunner/runner.py)
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/debug.py (rev 0)
+++ zope.testing/trunk/src/zope/testing/testrunner/debug.py 2008-08-13 08:21:57 UTC (rev 89786)
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2004-2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Debug functions
+
+$Id: __init__.py 86232 2008-05-03 15:09:33Z ctheune $
+
+"""
+
+import sys
+import pdb
+
+from zope.testing import doctest
+import zope.testing.testrunner.interfaces
+
+
+def post_mortem(exc_info):
+ err = exc_info[1]
+ if isinstance(err, (doctest.UnexpectedException, doctest.DocTestFailure)):
+
+ if isinstance(err, doctest.UnexpectedException):
+ exc_info = err.exc_info
+
+ # Print out location info if the error was in a doctest
+ if exc_info[2].tb_frame.f_code.co_filename == '<string>':
+ print_doctest_location(err)
+
+ else:
+ print_doctest_location(err)
+ # Hm, we have a DocTestFailure exception. We need to
+ # generate our own traceback
+ try:
+ exec ('raise ValueError'
+ '("Expected and actual output are different")'
+ ) in err.test.globs
+ except:
+ exc_info = sys.exc_info()
+
+ print "%s:" % (exc_info[0], )
+ print exc_info[1]
+ pdb.post_mortem(exc_info[2])
+ raise zope.testing.testrunner.interfaces.EndRun()
+
+
+def print_doctest_location(err):
+ # This mimics pdb's output, which gives way cool results in emacs :)
+ filename = err.test.filename
+ if filename.endswith('.pyc'):
+ filename = filename[:-1]
+ print "> %s(%s)_()" % (filename, err.test.lineno+err.example.lineno+1)
Modified: zope.testing/trunk/src/zope/testing/testrunner/find.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/find.py 2008-08-13 06:22:15 UTC (rev 89785)
+++ zope.testing/trunk/src/zope/testing/testrunner/find.py 2008-08-13 08:21:57 UTC (rev 89786)
@@ -23,21 +23,59 @@
import zope.testing.testrunner.feature
import zope.testing.testrunner.layer
+import zope.testing.testrunner.debug
identifier = re.compile(r'[_a-zA-Z]\w*$').match
class StartUpFailure(unittest.TestCase):
- """Empty test case added to the test suite to indicate import failures."""
+ """Empty test case added to the test suite to indicate import failures.
+ >>> class Options(object):
+ ... post_mortem = False
+ >>> options = Options()
+
+ Normally the StartUpFailure just acts as an emtpy test suite to satisfy
+ the test runner and statistics:
+
+ >>> StartUpFailure(options, None, None)
+ <StartUpFailure module=None>
+
+ The post mortem debugger needs real exception information:
+
+ >>> import sys
+ >>> try:
+ ... raise Exception()
+ ... except:
+ ... exc_info = sys.exc_info()
+
+ If the post mortem option is enabled the StartUpFailure will start
+ the debugger and stop the test run after the debugger quits:
+
+ >>> from zope.testing.testrunner.runner import FakeInputContinueGenerator
+ >>> old_stdin = sys.stdin
+
+ >>> options.post_mortem = True
+ >>> sys.stdin = FakeInputContinueGenerator()
+ >>> try:
+ ... StartUpFailure(options, None, exc_info)
+ ... finally:
+ ... sys.stdin = old_stdin
+ Traceback (most recent call last):
+ EndRun
+
+ """
+
def __init__(self, options, module, exc_info):
if options.post_mortem:
- from zope.testing.testrunner.runner import post_mortem
- post_mortem(exc_info)
+ zope.testing.testrunner.debug.post_mortem(exc_info)
self.module = module
self.exc_info = exc_info
+ def __repr__(self):
+ return '<StartUpFailure module=%s>' % self.module
+
def find_tests(options, found_suites=None):
"""Creates a dictionary mapping layer name to a suite of tests to be run
in that layer.
Modified: zope.testing/trunk/src/zope/testing/testrunner/interfaces.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/interfaces.py 2008-08-13 06:22:15 UTC (rev 89785)
+++ zope.testing/trunk/src/zope/testing/testrunner/interfaces.py 2008-08-13 08:21:57 UTC (rev 89786)
@@ -23,6 +23,14 @@
import zope.interface
+class EndRun(Exception):
+ """Indicate that the existing run call should stop
+
+ Used to prevent additional test output after post-mortem debugging.
+
+ """
+
+
class IFeature(zope.interface.Interface):
"""Features extend the test runners functionality in a pipe-lined
order.
Modified: zope.testing/trunk/src/zope/testing/testrunner/runner.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/runner.py 2008-08-13 06:22:15 UTC (rev 89785)
+++ zope.testing/trunk/src/zope/testing/testrunner/runner.py 2008-08-13 08:21:57 UTC (rev 89786)
@@ -20,7 +20,6 @@
import gc
import glob
import os
-import pdb
import re
import sys
import tempfile
@@ -45,8 +44,9 @@
import zope.testing.testrunner.listing
import zope.testing.testrunner.statistics
import zope.testing.testrunner.subprocess
+import zope.testing.testrunner.interfaces
+import zope.testing.testrunner.debug
-
PYREFCOUNT_PATTERN = re.compile('\[[0-9]+ refs\]')
@@ -66,14 +66,6 @@
"Couldn't tear down a test"
-class EndRun(Exception):
- """Indicate that the existing run call should stop
-
- Used to prevent additional test output after post-mortem debugging.
-
- """
-
-
class Runner(object):
"""The test runner.
@@ -214,7 +206,7 @@
try:
self.ran += run_layer(self.options, layer_name, layer, tests,
setup_layers, self.failures, self.errors)
- except EndRun:
+ except zope.testing.testrunner.interfaces.EndRun:
self.failed = True
return
except CanNotTearDown:
@@ -353,7 +345,7 @@
try:
setup_layer(options, layer, setup_layers)
- except EndRun:
+ except zope.testing.testrunner.interfaces.EndRun:
raise
except Exception:
f = cStringIO.StringIO()
@@ -537,7 +529,8 @@
% options.resume_layer)
raise
else:
- post_mortem(sys.exc_info())
+ zope.testing.testrunner.debug.post_mortem(
+ sys.exc_info())
else:
raise
@@ -608,7 +601,7 @@
" when running a layer"
" as a subprocess!")
else:
- post_mortem(exc_info)
+ zope.testing.testrunner.debug.post_mortem(exc_info)
def addFailure(self, test, exc_info):
self.options.output.test_failure(test, time.time() - self._start_time,
@@ -619,7 +612,7 @@
if self.options.post_mortem:
# XXX: mgedmin: why isn't there a resume_layer check here like
# in addError?
- post_mortem(exc_info)
+ zope.testing.testrunner.debug.post_mortem(exc_info)
def stopTest(self, test):
self.testTearDown()
@@ -690,42 +683,6 @@
gather_layers(b, result)
-def post_mortem(exc_info):
- err = exc_info[1]
- if isinstance(err, (doctest.UnexpectedException, doctest.DocTestFailure)):
-
- if isinstance(err, doctest.UnexpectedException):
- exc_info = err.exc_info
-
- # Print out location info if the error was in a doctest
- if exc_info[2].tb_frame.f_code.co_filename == '<string>':
- print_doctest_location(err)
-
- else:
- print_doctest_location(err)
- # Hm, we have a DocTestFailure exception. We need to
- # generate our own traceback
- try:
- exec ('raise ValueError'
- '("Expected and actual output are different")'
- ) in err.test.globs
- except:
- exc_info = sys.exc_info()
-
- print "%s:" % (exc_info[0], )
- print exc_info[1]
- pdb.post_mortem(exc_info[2])
- raise EndRun
-
-
-def print_doctest_location(err):
- # This mimics pdb's output, which gives way cool results in emacs :)
- filename = err.test.filename
- if filename.endswith('.pyc'):
- filename = filename[:-1]
- print "> %s(%s)_()" % (filename, err.test.lineno+err.example.lineno+1)
-
-
class FakeInputContinueGenerator:
def readline(self):
Modified: zope.testing/trunk/src/zope/testing/testrunner/tests.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/tests.py 2008-08-13 06:22:15 UTC (rev 89785)
+++ zope.testing/trunk/src/zope/testing/testrunner/tests.py 2008-08-13 08:21:57 UTC (rev 89786)
@@ -109,7 +109,8 @@
checker=checker),
doctest.DocTestSuite('zope.testing.testrunner'),
doctest.DocTestSuite('zope.testing.testrunner.coverage'),
- doctest.DocTestSuite('zope.testing.testrunner.options')
+ doctest.DocTestSuite('zope.testing.testrunner.options'),
+ doctest.DocTestSuite('zope.testing.testrunner.find'),
]
if sys.platform == 'win32':
More information about the Zope3-Checkins
mailing list