1+ from contextlib import contextmanager
2+ import sys
3+ import traceback
4+
15import pytest
2- from pytestqt .qt_compat import QtGui
6+
7+ from pytestqt .qt_compat import QtGui
38from pytestqt .qt_compat import QtTest
49
510
@@ -208,9 +213,30 @@ def stopForInteraction(self):
208213 stop = stopForInteraction
209214
210215
216+ @contextmanager
217+ def _capture_exceptions (self ):
218+ """
219+ Context manager that captures exceptions that happen insides it context,
220+ and returns them as a list of (type, value, traceback) after the
221+ context ends.
222+ """
223+ result = []
224+
225+ def hook (type_ , value , tback ):
226+ result .append ((type_ , value , tback ))
227+ sys .__excepthook__ (type_ , value , tback )
228+
229+ sys .excepthook = hook
230+ try :
231+ yield result
232+ finally :
233+ sys .excepthook = sys .__excepthook__
234+
235+
211236def pytest_configure (config ):
212237 """
213- PyTest plugin API. Called before the start of each test session.
238+ PyTest plugin API. Called before the start of each test session, used
239+ to instantiate the qApplication object that will be used for the session.
214240
215241 :param config.Config config:
216242 """
@@ -226,7 +252,7 @@ def exit_qapp():
226252 config ._cleanup .append (exit_qapp )
227253
228254
229- @pytest .fixture
255+ @pytest .yield_fixture
230256def qtbot (request ):
231257 """
232258 Fixture used to create a QtBot instance for using during testing.
@@ -235,6 +261,17 @@ def qtbot(request):
235261 that they are properly closed after the test ends.
236262 """
237263 result = QtBot (request .config .qt_app_instance )
238- request .addfinalizer (result ._close )
239- return result
264+ with result ._capture_exceptions () as exceptions :
265+ yield result
266+
267+ if exceptions :
268+ message = 'Qt exceptions in virtual methods:\n '
269+ message += '_' * 80 + '\n '
270+ for (exc_type , value , tback ) in exceptions :
271+ message += '' .join (traceback .format_tb (tback )) + '\n '
272+ message += '%s: %s\n ' % (exc_type .__name__ , value )
273+ message += '_' * 80 + '\n '
274+ pytest .fail (message )
275+
276+ result ._close ()
240277
0 commit comments