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

arigo at codespeak.net arigo at codespeak.net
Fri Sep 12 22:35:19 CEST 2008


Author: arigo
Date: Fri Sep 12 22:35:18 2008
New Revision: 58095

Modified:
   py/trunk/py/test/event.py
   py/trunk/py/test/report/terminal.py
   py/trunk/py/test/report/testing/test_terminal.py
   py/trunk/py/test/session.py
Log:
(pedronis, arigo)

KeyboardInterrupt handling:

    * in --verbose mode, print a detailed traceback at the end of
      the report.

    * in non-verbose mode, only print the file name and line number
      where the KeyboardInterrupt occurred.  That's the minimal
      amount of information that is of any help at all to locate
      an infinite loop somewhere.



Modified: py/trunk/py/test/event.py
==============================================================================
--- py/trunk/py/test/event.py	(original)
+++ py/trunk/py/test/event.py	Fri Sep 12 22:35:18 2008
@@ -45,8 +45,12 @@
         self.timestart = time.time()
 
 class TestrunFinish(BaseEvent):
-    def __init__(self, exitstatus=0):
+    def __init__(self, exitstatus=0, excinfo=None):
         self.exitstatus = exitstatus
+        if excinfo is None:
+            self.excrepr = None
+        else:
+            self.excrepr = excinfo.getrepr()
         self.timeend = time.time()
 
 class InternalException(BaseEvent):

Modified: py/trunk/py/test/report/terminal.py
==============================================================================
--- py/trunk/py/test/report/terminal.py	(original)
+++ py/trunk/py/test/report/terminal.py	Fri Sep 12 22:35:18 2008
@@ -132,6 +132,8 @@
         if ev.exitstatus in (0, 1, 2):
             self.summary_failures()
             self.summary_skips()
+        if ev.excrepr is not None:
+            self.summary_final_exc(ev.excrepr)
         if ev.exitstatus == 2:
             self.write_sep("!", "KEYBOARD INTERRUPT")
         self.summary_deselected()
@@ -201,6 +203,13 @@
                 for num, fspath, lineno, reason in folded_skips:
                     self._tw.line("%s:%d: [%d] %s" %(fspath, lineno, num, reason))
 
+    def summary_final_exc(self, excrepr):
+        self.write_sep("!")
+        if self.config.option.verbose:
+            excrepr.toterminal(self._tw)
+        else:
+            excrepr.reprcrash.toterminal(self._tw)
+
     def out_hostinfo(self):
         self._tw.line("host 0: %s %s - Python %s" %
                        (py.std.sys.platform, 

Modified: py/trunk/py/test/report/testing/test_terminal.py
==============================================================================
--- py/trunk/py/test/report/testing/test_terminal.py	(original)
+++ py/trunk/py/test/report/testing/test_terminal.py	Fri Sep 12 22:35:18 2008
@@ -207,25 +207,41 @@
         print s
         assert s.find("test_show_path_before_running_test.py") != -1
 
-    def test_keyboard_interrupt(self):
+    def test_keyboard_interrupt(self, verbose=False):
         modcol = self.getmodulecol("""
             def test_foobar():
                 assert 0
             def test_spamegg():
                 import py; py.test.skip('skip me please!')
-        """, configargs=("--showskipsummary",), withsession=True)
+            def test_interrupt_me():
+                raise KeyboardInterrupt   # simulating the user
+        """, configargs=("--showskipsummary",) + ("-v",)*verbose,
+             withsession=True)
         stringio = py.std.cStringIO.StringIO()
         rep = TerminalReporter(modcol._config, bus=self.session.bus, file=stringio)
         rep.processevent(event.TestrunStart())
-        for item in self.session.genitems([modcol]):
-            ev = basic_run_report(item) 
-            rep.processevent(ev)
+        try:
+            for item in self.session.genitems([modcol]):
+                ev = basic_run_report(item) 
+                rep.processevent(ev)
+        except KeyboardInterrupt:
+            excinfo = py.code.ExceptionInfo()
+        else:
+            py.test.fail("no KeyboardInterrupt??")
         s = popvalue(stringio)
-        assert s.find("test_keyboard_interrupt.py Fs") != -1
-        rep.processevent(event.TestrunFinish(exitstatus=2))
+        if not verbose:
+            assert s.find("_keyboard_interrupt.py Fs") != -1
+        rep.processevent(event.TestrunFinish(exitstatus=2, excinfo=excinfo))
         assert_stringio_contains_lines(stringio, [
             "    def test_foobar():",
             ">       assert 0",
             "E       assert 0",
         ])
-        assert "Skipped: 'skip me please!'" in stringio.getvalue()
+        text = stringio.getvalue()
+        assert "Skipped: 'skip me please!'" in text
+        assert "_keyboard_interrupt.py:6: KeyboardInterrupt" in text
+        see_details = "raise KeyboardInterrupt   # simulating the user" in text
+        assert see_details == verbose
+
+    def test_verbose_keyboard_interrupt(self):
+        self.test_keyboard_interrupt(verbose=True)

Modified: py/trunk/py/test/session.py
==============================================================================
--- py/trunk/py/test/session.py	(original)
+++ py/trunk/py/test/session.py	Fri Sep 12 22:35:18 2008
@@ -103,9 +103,10 @@
             if self.config.option.exitfirst: 
                 self.shouldstop = True 
 
-    def sessionfinishes(self, exitstatus=0):
+    def sessionfinishes(self, exitstatus=0, excinfo=None):
         """ teardown any resources after a test run. """ 
-        self.bus.notify(event.TestrunFinish(exitstatus=exitstatus))
+        self.bus.notify(event.TestrunFinish(exitstatus=exitstatus,
+                                            excinfo=excinfo))
         self.bus.unsubscribe(self._processfailures)
         #self.reporter.deactivate()
         return self._failurelist 
@@ -123,6 +124,7 @@
         self.sessionstarts()
         self.bus.notify(makehostup())
         exitstatus = outcome.EXIT_OK
+        captured_excinfo = None
         try:
             for item in self.collect(colitems): 
                 if self.shouldstop: 
@@ -131,13 +133,14 @@
                     self.runtest(item)
             py.test.collect.Item._setupstate.teardown_all()
         except KeyboardInterrupt:
+            captured_excinfo = py.code.ExceptionInfo()
             exitstatus = outcome.EXIT_INTERRUPTED
         except:
             self.bus.notify(event.InternalException())
             exitstatus = outcome.EXIT_INTERNALERROR
         if self._failurelist and exitstatus == 0:
             exitstatus = outcome.EXIT_TESTSFAILED
-        self.sessionfinishes(exitstatus=exitstatus)
+        self.sessionfinishes(exitstatus=exitstatus, excinfo=captured_excinfo)
         return exitstatus
 
     def runpdb(self, excinfo):



More information about the pytest-commit mailing list