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:
|
class PdbInvoke:
|
||||||
@pytest.mark.tryfirst
|
@pytest.mark.tryfirst
|
||||||
def pytest_runtest_makereport(self, item, call, __multicall__):
|
def pytest_runtest_makereport(self, item, call, __multicall__):
|
||||||
|
rep = __multicall__.execute()
|
||||||
if not call.excinfo or \
|
if not call.excinfo or \
|
||||||
call.excinfo.errisinstance(pytest.skip.Exception) or \
|
call.excinfo.errisinstance(pytest.skip.Exception) or \
|
||||||
call.excinfo.errisinstance(py.std.bdb.BdbQuit):
|
call.excinfo.errisinstance(py.std.bdb.BdbQuit):
|
||||||
return
|
return rep
|
||||||
rep = __multicall__.execute()
|
|
||||||
if "xfail" in rep.keywords:
|
if "xfail" in rep.keywords:
|
||||||
return rep
|
return rep
|
||||||
# we assume that the above execute() suspended capturing
|
# we assume that the above execute() suspended capturing
|
||||||
|
|
|
@ -44,8 +44,8 @@ class TestCaseFunction(pytest.Function):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _addexcinfo(self, rawexcinfo):
|
def _addexcinfo(self, rawexcinfo):
|
||||||
#__tracebackhide__ = True
|
# unwrap potential exception info (see twisted trial support below)
|
||||||
assert rawexcinfo
|
rawexcinfo = getattr(rawexcinfo, '_rawexcinfo', rawexcinfo)
|
||||||
try:
|
try:
|
||||||
self._excinfo = py.code.ExceptionInfo(rawexcinfo)
|
self._excinfo = py.code.ExceptionInfo(rawexcinfo)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -60,10 +60,10 @@ class TestCaseFunction(pytest.Function):
|
||||||
except:
|
except:
|
||||||
pytest.fail("ERROR: Unknown Incompatible Exception "
|
pytest.fail("ERROR: Unknown Incompatible Exception "
|
||||||
"representation:\n%r" %(rawexcinfo,), pytrace=False)
|
"representation:\n%r" %(rawexcinfo,), pytrace=False)
|
||||||
except pytest.fail.Exception:
|
|
||||||
self._excinfo = py.code.ExceptionInfo()
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
|
except pytest.fail.Exception:
|
||||||
|
self._excinfo = py.code.ExceptionInfo()
|
||||||
|
|
||||||
def addError(self, testcase, rawexcinfo):
|
def addError(self, testcase, rawexcinfo):
|
||||||
self._addexcinfo(rawexcinfo)
|
self._addexcinfo(rawexcinfo)
|
||||||
|
@ -84,3 +84,30 @@ def pytest_runtest_makereport(item, call):
|
||||||
call.excinfo = item._excinfo
|
call.excinfo = item._excinfo
|
||||||
item._excinfo = None
|
item._excinfo = None
|
||||||
del call.result
|
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
|
(c) Holger Krekel and others, 2004-2010
|
||||||
"""
|
"""
|
||||||
__version__ = '2.0.0.dev36'
|
__version__ = '2.0.0.dev37'
|
||||||
__all__ = ['main']
|
__all__ = ['main']
|
||||||
|
|
||||||
from _pytest.core import main, UsageError, _preloadplugins
|
from _pytest.core import main, UsageError, _preloadplugins
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -22,7 +22,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple powerful testing with Python',
|
description='py.test: simple powerful testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='2.0.0.dev36',
|
version='2.0.0.dev37',
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
|
@ -185,3 +185,107 @@ def test_testcase_totally_incompatible_exception_info(testdir):
|
||||||
item.addError(None, 42)
|
item.addError(None, 42)
|
||||||
excinfo = item._excinfo
|
excinfo = item._excinfo
|
||||||
assert 'ERROR: Unknown Incompatible' in str(excinfo.getrepr())
|
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 \
|
py.test -n3 -rfsxX \
|
||||||
--junitxml={envlogdir}/junit-{envname}.xml []
|
--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]
|
[testenv:doctest]
|
||||||
changedir=.
|
changedir=.
|
||||||
commands=py.test --doctest-modules _pytest
|
commands=py.test --doctest-modules _pytest
|
||||||
|
|
Loading…
Reference in New Issue