fix #6 : allow skip/xfail/pdb with trial by hacking the raw exception info out from trial
This commit is contained in:
parent
b40a0c18b1
commit
9be1cd8007
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
2
setup.py
2
setup.py
|
@ -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'],
|
||||
|
|
|
@ -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()*",
|
||||
])
|
||||
|
|
7
tox.ini
7
tox.ini
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue