fix #6 : allow skip/xfail/pdb with trial by hacking the raw exception info out from trial

This commit is contained in:
holger krekel 2010-11-24 11:48:55 +01:00
parent b40a0c18b1
commit 9be1cd8007
6 changed files with 146 additions and 8 deletions

View File

@ -44,11 +44,11 @@ def pytest_runtest_makereport():
class PdbInvoke:
@pytest.mark.tryfirst
def pytest_runtest_makereport(self, item, call, __multicall__):
rep = __multicall__.execute()
if not call.excinfo or \
call.excinfo.errisinstance(pytest.skip.Exception) or \
call.excinfo.errisinstance(py.std.bdb.BdbQuit):
return
rep = __multicall__.execute()
return rep
if "xfail" in rep.keywords:
return rep
# we assume that the above execute() suspended capturing

View File

@ -44,8 +44,8 @@ class TestCaseFunction(pytest.Function):
pass
def _addexcinfo(self, rawexcinfo):
#__tracebackhide__ = True
assert rawexcinfo
# unwrap potential exception info (see twisted trial support below)
rawexcinfo = getattr(rawexcinfo, '_rawexcinfo', rawexcinfo)
try:
self._excinfo = py.code.ExceptionInfo(rawexcinfo)
except TypeError:
@ -60,10 +60,10 @@ class TestCaseFunction(pytest.Function):
except:
pytest.fail("ERROR: Unknown Incompatible Exception "
"representation:\n%r" %(rawexcinfo,), pytrace=False)
except pytest.fail.Exception:
self._excinfo = py.code.ExceptionInfo()
except KeyboardInterrupt:
raise
except pytest.fail.Exception:
self._excinfo = py.code.ExceptionInfo()
def addError(self, testcase, rawexcinfo):
self._addexcinfo(rawexcinfo)
@ -84,3 +84,30 @@ def pytest_runtest_makereport(item, call):
call.excinfo = item._excinfo
item._excinfo = None
del call.result
# twisted trial support
def pytest_runtest_protocol(item, __multicall__):
if isinstance(item, TestCaseFunction):
if 'twisted.trial.unittest' in sys.modules:
ut = sys.modules['twisted.python.failure']
Failure__init__ = ut.Failure.__init__.im_func
check_testcase_implements_trial_reporter()
def excstore(self, exc_value=None, exc_type=None, exc_tb=None):
if exc_value is None:
self._rawexcinfo = sys.exc_info()
else:
self._rawexcinfo = (exc_value, exc_type, exc_tb)
Failure__init__(self, exc_value, exc_type, exc_tb)
ut.Failure.__init__ = excstore
try:
return __multicall__.execute()
finally:
ut.Failure.__init__ = Failure__init__
def check_testcase_implements_trial_reporter(done=[]):
if done:
return
from zope.interface import classImplements
from twisted.trial.itrial import IReporter
classImplements(TestCaseFunction, IReporter)
done.append(1)

View File

@ -5,7 +5,7 @@ see http://pytest.org for documentation and details
(c) Holger Krekel and others, 2004-2010
"""
__version__ = '2.0.0.dev36'
__version__ = '2.0.0.dev37'
__all__ = ['main']
from _pytest.core import main, UsageError, _preloadplugins

View File

@ -22,7 +22,7 @@ def main():
name='pytest',
description='py.test: simple powerful testing with Python',
long_description = long_description,
version='2.0.0.dev36',
version='2.0.0.dev37',
url='http://pytest.org',
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

View File

@ -185,3 +185,107 @@ def test_testcase_totally_incompatible_exception_info(testdir):
item.addError(None, 42)
excinfo = item._excinfo
assert 'ERROR: Unknown Incompatible' in str(excinfo.getrepr())
class TestTrialUnittest:
def setup_class(cls):
pytest.importorskip("twisted.trial.unittest")
def test_trial_exceptions_with_skips(self, testdir):
testdir.makepyfile("""
from twisted.trial import unittest
import pytest
class TC(unittest.TestCase):
def test_hello(self):
pytest.skip("skip_in_method")
@pytest.mark.skipif("sys.version_info != 1")
def test_hello2(self):
pass
@pytest.mark.xfail(reason="iwanto")
def test_hello3(self):
assert 0
def test_hello4(self):
pytest.xfail("i2wanto")
class TC2(unittest.TestCase):
def setup_class(cls):
pytest.skip("skip_in_setup_class")
def test_method(self):
pass
""")
result = testdir.runpytest("-rxs")
assert result.ret == 0
result.stdout.fnmatch_lines_random([
"*skip_in_setup_class*",
"*iwanto*",
"*i2wanto*",
"*sys.version_info*",
"*skip_in_method*",
"*3 skipped*2 xfail*",
])
def test_trial_pdb(self, testdir):
p = testdir.makepyfile("""
from twisted.trial import unittest
import pytest
class TC(unittest.TestCase):
def test_hello(self):
assert 0, "hellopdb"
""")
child = testdir.spawn_pytest(p)
child.expect("hellopdb")
child.sendeof()
def test_djangolike_testcase(testdir):
# contributed from Morten Breekevold
testdir.makepyfile("""
from unittest import TestCase, main
class DjangoLikeTestCase(TestCase):
def setUp(self):
print ("setUp()")
def test_presetup_has_been_run(self):
print ("test_thing()")
self.assertTrue(hasattr(self, 'was_presetup'))
def tearDown(self):
print ("tearDown()")
def __call__(self, result=None):
try:
self._pre_setup()
except (KeyboardInterrupt, SystemExit):
raise
except Exception:
import sys
result.addError(self, sys.exc_info())
return
super(DjangoLikeTestCase, self).__call__(result)
try:
self._post_teardown()
except (KeyboardInterrupt, SystemExit):
raise
except Exception:
import sys
result.addError(self, sys.exc_info())
return
def _pre_setup(self):
print ("_pre_setup()")
self.was_presetup = True
def _post_teardown(self):
print ("_post_teardown()")
""")
result = testdir.runpytest("-s")
assert result.ret == 0
result.stdout.fnmatch_lines([
"*_pre_setup()*",
"*setUp()*",
"*test_thing()*",
"*tearDown()*",
"*_post_teardown()*",
])

View File

@ -25,6 +25,13 @@ commands=
py.test -n3 -rfsxX \
--junitxml={envlogdir}/junit-{envname}.xml []
[testenv:trial]
changedir=.
basepython=python2.6
deps=:pypi:twisted
commands=
py.test -rsxf \
--junitxml={envlogdir}/junit-{envname}.xml [testing/test_unittest.py]
[testenv:doctest]
changedir=.
commands=py.test --doctest-modules _pytest