[svn r62662] introduce another hook "pytest_item_makereport" to allow a

correct implementation of the xfail plugin: previously
--pdb and -x would incorrrectly terminate if seeing
a marked-to-fail test.

--HG--
branch : trunk
This commit is contained in:
hpk 2009-03-06 19:07:44 +01:00
parent e9f275b176
commit 7124b9e941
4 changed files with 41 additions and 6 deletions

View File

@ -114,6 +114,10 @@ class DefaultPlugin:
from py.__.test.dsession.dsession import DSession
config.setsessionclass(DSession)
def pytest_item_makereport(self, item, excinfo, when, outerr):
from py.__.test import event
return event.ItemTestReport(item, excinfo, when, outerr)
def test_implied_different_sessions(tmpdir):
def x(*args):
config = py.test.config._reparse([tmpdir] + list(args))

View File

@ -60,6 +60,8 @@ class PluginTester(Support):
if not hasattr(hook, 'func_code'):
continue # XXX do some checks on attributes as well?
method_args = getargs(method.func_code)
if '__call__' in method_args[0]:
method_args[0].remove('__call__')
hookargs = getargs(hook.func_code)
for arg, hookarg in zip(method_args[0], hookargs[0]):
if arg != hookarg:
@ -119,6 +121,9 @@ class PytestPluginHooks:
def pytest_pyfunc_call(self, pyfuncitem, args, kwargs):
""" return True if we consumed/did the call to the python function item. """
def pytest_item_makereport(self, item, excinfo, when, outerr):
""" return ItemTestReport event for the given test outcome. """
# collection hooks
def pytest_collect_file(self, path, parent):
""" return Collection node or None. """
@ -134,6 +139,11 @@ class PytestPluginHooks:
def pytest_pymodule_makeitem(self, modcol, name, obj):
""" return custom item/collector for a python object in a module, or None. """
# from pytest_terminal plugin
def pytest_report_teststatus(self, event):
""" return shortletter and verbose word. """
# from pytest_terminal plugin
def pytest_report_teststatus(self, event):
""" return shortletter and verbose word. """

View File

@ -9,12 +9,25 @@ import py
class XfailPlugin(object):
""" mark and report specially about "expected to fail" tests. """
def pytest_item_makereport(self, __call__, item, excinfo, when, outerr):
if hasattr(item, 'obj') and hasattr(item.obj, 'func_dict'):
if 'xfail' in item.obj.func_dict:
res = __call__.execute(firstresult=True)
if excinfo:
res.skipped = True
res.failed = res.passed = False
else:
res.skipped = res.passed = False
res.failed = True
return res
def pytest_report_teststatus(self, event):
""" return shortletter and verbose word. """
if 'xfail' in event.keywords:
if event.failed:
if event.skipped:
return "xfailed", "x", "xfail"
else:
elif event.failed:
return "xpassed", "P", "xpass"
# a hook implemented called by the terminalreporter instance/plugin
@ -22,7 +35,7 @@ class XfailPlugin(object):
tr = terminalreporter
xfailed = tr.stats.get("xfailed")
if xfailed:
tr.write_sep("_", "EXPECTED XFAILURES")
tr.write_sep("_", "expected failures")
for event in xfailed:
entry = event.longrepr.reprcrash
key = entry.path, entry.lineno, entry.message
@ -33,7 +46,7 @@ class XfailPlugin(object):
xpassed = terminalreporter.stats.get("xpassed")
if xpassed:
tr.write_sep("_", "UNEXPECTEDLY PASSING")
tr.write_sep("_", "UNEXPECTEDLY PASSING TESTS")
for event in xpassed:
tr._tw.line("%s: xpassed" %(event.colitem,))
@ -54,10 +67,16 @@ def test_xfail(plugintester, linecomp):
@py.test.mark.xfail
def test_this():
assert 0
@py.test.mark.xfail
def test_that():
assert 1
""")
result = testdir.runpytest(p)
extra = result.stdout.fnmatch_lines([
"*XFAILURES*",
"*expected failures*",
"*test_one.test_this*test_one.py:5*",
"*UNEXPECTEDLY PASSING*",
"*test_that*",
])
assert result.ret == 1

View File

@ -59,7 +59,9 @@ class ItemRunner(RobustRun):
#self.colitem.config.pytestplugins.post_execute(self.colitem)
def makereport(self, res, when, excinfo, outerr):
testrep = event.ItemTestReport(self.colitem, excinfo, when, outerr)
testrep = self.colitem._config.pytestplugins.call_firstresult(
"pytest_item_makereport", item=self.colitem,
excinfo=excinfo, when=when, outerr=outerr)
if self.pdb and testrep.failed:
tw = py.io.TerminalWriter()
testrep.toterminal(tw)