[py-svn] r63797 - in py/trunk/py/test: . testing

hpk at codespeak.net hpk at codespeak.net
Tue Apr 7 16:28:01 CEST 2009


Author: hpk
Date: Tue Apr  7 16:27:57 2009
New Revision: 63797

Modified:
   py/trunk/py/test/config.py
   py/trunk/py/test/runner.py
   py/trunk/py/test/testing/test_config.py
Log:
introduce a clean "guardedcall" interface for performing calls with exception catching and stdout/stderr capturing


Modified: py/trunk/py/test/config.py
==============================================================================
--- py/trunk/py/test/config.py	(original)
+++ py/trunk/py/test/config.py	Tue Apr  7 16:27:57 2009
@@ -286,6 +286,28 @@
             roots.append(pydir)
         return roots 
 
+    def guardedcall(self, func):
+        excinfo = result = None
+        capture = self._getcapture()
+        try:
+            try:
+                result = func()
+            except KeyboardInterrupt:
+                raise
+            except:
+                excinfo = py.code.ExceptionInfo()
+        finally:
+            stdout, stderr = capture.reset()
+        return CallResult(result, excinfo, stdout, stderr)
+
+class CallResult:
+    def __init__(self, result, excinfo, stdout, stderr):
+        self.stdout = stdout 
+        self.stderr = stderr
+        self.outerr = (self.stdout, self.stderr)
+        self.excinfo = excinfo
+        if excinfo is None:
+            self.result = result 
     
 #
 # helpers

Modified: py/trunk/py/test/runner.py
==============================================================================
--- py/trunk/py/test/runner.py	(original)
+++ py/trunk/py/test/runner.py	Tue Apr  7 16:27:57 2009
@@ -198,41 +198,22 @@
             self.stack.append(col) 
 
     def do_setup(self, item):
-        excinfo, outerr = guarded_call(item.config._getcapture(), 
-                lambda: self.prepare(item)
-        )
-        rep = ItemSetupReport(item, excinfo, outerr)
+        call = item.config.guardedcall(lambda: self.prepare(item))
+        rep = ItemSetupReport(item, call.excinfo, call.outerr)
         item.config.pytestplugins.notify("itemsetupreport", rep)
-        return not excinfo 
+        return not call.excinfo 
 
     def do_teardown(self, item):
-        excinfo, outerr = guarded_call(item.config._getcapture(), 
-                lambda: self.teardown_exact(item)
-        )
-        if excinfo:
-            rep = ItemSetupReport(item, excinfo, outerr)
+        call = item.config.guardedcall(lambda: self.teardown_exact(item))
+        if call.excinfo:
+            rep = ItemSetupReport(item, call.excinfo, call.outerr)
             item.config.pytestplugins.notify("itemsetupreport", rep)
 
     def do_fixture_and_runtest(self, item):
         """ setup fixture and perform actual item.runtest(). """
         if self.do_setup(item):
-            excinfo, outerr = guarded_call(item.config._getcapture(), 
-                   lambda: item.runtest())
+            call = item.config.guardedcall(lambda: item.runtest())
             item.config.pytestplugins.notify(
                 "item_runtest_finished", 
-                item=item, excinfo=excinfo, outerr=outerr)
+                item=item, excinfo=call.excinfo, outerr=call.outerr)
             self.do_teardown(item)
-
-def guarded_call(capture, call):
-    excinfo = None
-    try:
-        try:
-            call()
-        except (KeyboardInterrupt, Exit):
-            raise
-        except:
-            excinfo = py.code.ExceptionInfo()
-    finally:
-        outerr = capture.reset()
-    return excinfo, outerr 
-

Modified: py/trunk/py/test/testing/test_config.py
==============================================================================
--- py/trunk/py/test/testing/test_config.py	(original)
+++ py/trunk/py/test/testing/test_config.py	Tue Apr  7 16:27:57 2009
@@ -137,8 +137,7 @@
         assert pl[1] == somepath
 
     def test_setsessionclass_and_initsession(self, testdir):
-        from py.__.test.config import Config 
-        config = Config()
+        config = testdir.Config()
         class Session1: 
             def __init__(self, config):
                 self.config = config 
@@ -149,7 +148,6 @@
         py.test.raises(ValueError, "config.setsessionclass(Session1)")
 
 
-
 class TestConfigApi_getcolitems:
     def test_getcolitems_onedir(self, tmpdir):
         config = py.test.config._reparse([tmpdir])
@@ -214,6 +212,37 @@
             assert col.config is config 
 
 
+class TestGuardedCall:
+    def test_guardedcall_ok(self, testdir):
+        config = testdir.parseconfig()
+        def myfunc(x):
+            print x
+            print >>py.std.sys.stderr, "hello"
+            return 7
+        call = config.guardedcall(lambda: myfunc(3))
+        assert call.excinfo is None
+        assert call.result == 7
+        assert call.stdout.startswith("3")
+        assert call.stderr.startswith("hello")
+
+    def test_guardedcall_fail(self, testdir):
+        config = testdir.parseconfig()
+        def myfunc(x):
+            print x
+            raise ValueError(17)
+        call = config.guardedcall(lambda: myfunc(3))
+        assert call.excinfo 
+        assert call.excinfo.type == ValueError 
+        assert not hasattr(call, 'result')
+        assert call.stdout.startswith("3")
+        assert not call.stderr 
+
+    def test_guardedcall_keyboardinterrupt(self, testdir):
+        config = testdir.parseconfig()
+        def myfunc():
+            raise KeyboardInterrupt
+        py.test.raises(KeyboardInterrupt, config.guardedcall, myfunc)
+
 class TestOptionEffects:
     def test_boxed_option_default(self, testdir):
         tmpdir = testdir.tmpdir.ensure("subdir", dir=1)



More information about the pytest-commit mailing list