remove externally setting and dealing with "item.outerr" from capturing in favor of a direct interface for adding reporting sections to items.
* * * refactor makereport implementation to avoid recursion with __multicall__
This commit is contained in:
parent
cde970be69
commit
b47fdbe0a7
|
@ -151,8 +151,6 @@ class CaptureManager:
|
|||
|
||||
def resumecapture_item(self, item):
|
||||
method = self._getmethod(item.config, item.fspath)
|
||||
if not hasattr(item, 'outerr'):
|
||||
item.outerr = ('', '') # we accumulate outerr on the item
|
||||
return self.resumecapture(method)
|
||||
|
||||
def resumecapture(self, method=None):
|
||||
|
@ -174,16 +172,10 @@ class CaptureManager:
|
|||
self.deactivate_funcargs()
|
||||
if hasattr(self, '_capturing'):
|
||||
method = self._capturing
|
||||
del self._capturing
|
||||
cap = self._method2capture.get(method)
|
||||
if cap is not None:
|
||||
outerr = cap.suspend()
|
||||
del self._capturing
|
||||
if item:
|
||||
outerr = (item.outerr[0] + outerr[0],
|
||||
item.outerr[1] + outerr[1])
|
||||
return outerr
|
||||
if hasattr(item, 'outerr'):
|
||||
return item.outerr
|
||||
return cap.suspend()
|
||||
return "", ""
|
||||
|
||||
def activate_funcargs(self, pyfuncitem):
|
||||
|
@ -235,18 +227,14 @@ class CaptureManager:
|
|||
self.suspendcapture()
|
||||
|
||||
@pytest.mark.tryfirst
|
||||
def pytest_runtest_makereport(self, __multicall__, item, call):
|
||||
def pytest_runtest_makereport(self, item, call):
|
||||
funcarg_outerr = self.deactivate_funcargs()
|
||||
rep = __multicall__.execute()
|
||||
outerr = self.suspendcapture(item)
|
||||
out, err = self.suspendcapture(item)
|
||||
if funcarg_outerr is not None:
|
||||
outerr = (outerr[0] + funcarg_outerr[0],
|
||||
outerr[1] + funcarg_outerr[1])
|
||||
addouterr(rep, outerr)
|
||||
if not rep.passed or rep.when == "teardown":
|
||||
outerr = ('', '')
|
||||
item.outerr = outerr
|
||||
return rep
|
||||
out += funcarg_outerr[0]
|
||||
err += funcarg_outerr[1]
|
||||
item.add_report_section(call.when, "out", out)
|
||||
item.add_report_section(call.when, "err", err)
|
||||
|
||||
error_capsysfderror = "cannot use capsys and capfd at the same time"
|
||||
|
||||
|
|
|
@ -108,12 +108,14 @@ class LogXML(object):
|
|||
))
|
||||
|
||||
def _write_captured_output(self, report):
|
||||
sec = dict(report.sections)
|
||||
for name in ('out', 'err'):
|
||||
content = sec.get("Captured std%s" % name)
|
||||
if content:
|
||||
tag = getattr(Junit, 'system-'+name)
|
||||
self.append(tag(bin_xml_escape(content)))
|
||||
for capname in ('out', 'err'):
|
||||
allcontent = ""
|
||||
for name, content in report.get_sections("Captured std%s" %
|
||||
capname):
|
||||
allcontent += content
|
||||
if allcontent:
|
||||
tag = getattr(Junit, 'system-'+capname)
|
||||
self.append(tag(bin_xml_escape(allcontent)))
|
||||
|
||||
def append(self, obj):
|
||||
self.tests[-1].append(obj)
|
||||
|
|
|
@ -233,6 +233,7 @@ class Node(object):
|
|||
|
||||
# used for storing artificial fixturedefs for direct parametrization
|
||||
self._name2pseudofixturedef = {}
|
||||
|
||||
#self.extrainit()
|
||||
|
||||
@property
|
||||
|
@ -469,6 +470,14 @@ class Item(Node):
|
|||
"""
|
||||
nextitem = None
|
||||
|
||||
def __init__(self, name, parent=None, config=None, session=None):
|
||||
super(Item, self).__init__(name, parent, config, session)
|
||||
self._report_sections = []
|
||||
|
||||
def add_report_section(self, when, key, content):
|
||||
if content:
|
||||
self._report_sections.append((when, key, content))
|
||||
|
||||
def reportinfo(self):
|
||||
return self.fspath, None, ""
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ class pytestPDB:
|
|||
if item is not None:
|
||||
capman = item.config.pluginmanager.getplugin("capturemanager")
|
||||
out, err = capman.suspendcapture()
|
||||
if hasattr(item, 'outerr'):
|
||||
item.outerr = (item.outerr[0] + out, item.outerr[1] + err)
|
||||
#if hasattr(item, 'outerr'):
|
||||
# item.outerr = (item.outerr[0] + out, item.outerr[1] + err)
|
||||
tw = py.io.TerminalWriter()
|
||||
tw.line()
|
||||
tw.sep(">", "PDB set_trace (IO-capturing turned off)")
|
||||
|
|
|
@ -178,6 +178,11 @@ class BaseReport(object):
|
|||
except UnicodeEncodeError:
|
||||
out.line("<unprintable longrepr>")
|
||||
|
||||
def get_sections(self, prefix):
|
||||
for name, content in self.sections:
|
||||
if name.startswith(prefix):
|
||||
yield prefix, content
|
||||
|
||||
passed = property(lambda x: x.outcome == "passed")
|
||||
failed = property(lambda x: x.outcome == "failed")
|
||||
skipped = property(lambda x: x.outcome == "skipped")
|
||||
|
@ -191,6 +196,7 @@ def pytest_runtest_makereport(item, call):
|
|||
duration = call.stop-call.start
|
||||
keywords = dict([(x,1) for x in item.keywords])
|
||||
excinfo = call.excinfo
|
||||
sections = []
|
||||
if not call.excinfo:
|
||||
outcome = "passed"
|
||||
longrepr = None
|
||||
|
@ -209,16 +215,18 @@ def pytest_runtest_makereport(item, call):
|
|||
else: # exception in setup or teardown
|
||||
longrepr = item._repr_failure_py(excinfo,
|
||||
style=item.config.option.tbstyle)
|
||||
for rwhen, key, content in item._report_sections:
|
||||
sections.append(("Captured std%s %s" %(key, rwhen), content))
|
||||
return TestReport(item.nodeid, item.location,
|
||||
keywords, outcome, longrepr, when,
|
||||
duration=duration)
|
||||
sections, duration)
|
||||
|
||||
class TestReport(BaseReport):
|
||||
""" Basic test report object (also used for setup and teardown calls if
|
||||
they fail).
|
||||
"""
|
||||
def __init__(self, nodeid, location,
|
||||
keywords, outcome, longrepr, when, sections=(), duration=0, **extra):
|
||||
def __init__(self, nodeid, location, keywords, outcome,
|
||||
longrepr, when, sections=(), duration=0, **extra):
|
||||
#: normalized collection node id
|
||||
self.nodeid = nodeid
|
||||
|
||||
|
|
|
@ -282,9 +282,9 @@ class TestPerTestCapturing:
|
|||
"====* FAILURES *====",
|
||||
"____*____",
|
||||
"*test_capturing_outerr.py:8: ValueError",
|
||||
"*--- Captured stdout ---*",
|
||||
"*--- Captured stdout *call*",
|
||||
"1",
|
||||
"*--- Captured stderr ---*",
|
||||
"*--- Captured stderr *call*",
|
||||
"2",
|
||||
])
|
||||
|
||||
|
|
|
@ -478,10 +478,12 @@ def test_unicode_issue368(testdir):
|
|||
path = testdir.tmpdir.join("test.xml")
|
||||
log = LogXML(str(path), None)
|
||||
ustr = py.builtin._totext("ВНИ!", "utf-8")
|
||||
class report:
|
||||
from _pytest.runner import BaseReport
|
||||
class Report(BaseReport):
|
||||
longrepr = ustr
|
||||
sections = []
|
||||
nodeid = "something"
|
||||
report = Report()
|
||||
|
||||
# hopefully this is not too brittle ...
|
||||
log.pytest_sessionstart()
|
||||
|
|
Loading…
Reference in New Issue