fix skip reporting over distributed testing. if we have a "skip" report
rep.longrepr will now be a 3-tuple (path, lineno, message)
This commit is contained in:
parent
1bc444d5c8
commit
82ba645a2e
|
@ -74,17 +74,18 @@ class ResultLog(object):
|
|||
elif report.failed:
|
||||
longrepr = str(report.longrepr)
|
||||
elif report.skipped:
|
||||
longrepr = str(report.longrepr.reprcrash.message)
|
||||
longrepr = str(report.longrepr[2])
|
||||
self.log_outcome(report, code, longrepr)
|
||||
|
||||
def pytest_collectreport(self, report):
|
||||
if not report.passed:
|
||||
if report.failed:
|
||||
code = "F"
|
||||
longrepr = str(report.longrepr.reprcrash)
|
||||
else:
|
||||
assert report.skipped
|
||||
code = "S"
|
||||
longrepr = str(report.longrepr.reprcrash)
|
||||
longrepr = "%s:%d: %s" % report.longrepr
|
||||
self.log_outcome(report, code, longrepr)
|
||||
|
||||
def pytest_internalerror(self, excrepr):
|
||||
|
|
|
@ -111,9 +111,21 @@ class CallInfo:
|
|||
status = "result: %r" % (self.result,)
|
||||
return "<CallInfo when=%r %s>" % (self.when, status)
|
||||
|
||||
def getslaveinfoline(node):
|
||||
try:
|
||||
return node._slaveinfocache
|
||||
except AttributeError:
|
||||
d = node.slaveinfo
|
||||
ver = "%s.%s.%s" % d['version_info'][:3]
|
||||
node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
|
||||
d['id'], d['sysplatform'], ver, d['executable'])
|
||||
return s
|
||||
|
||||
class BaseReport(object):
|
||||
def toterminal(self, out):
|
||||
longrepr = self.longrepr
|
||||
if hasattr(self, 'node'):
|
||||
out.line(getslaveinfoline(self.node))
|
||||
if hasattr(longrepr, 'toterminal'):
|
||||
longrepr.toterminal(out)
|
||||
else:
|
||||
|
@ -140,7 +152,8 @@ def pytest_runtest_makereport(item, call):
|
|||
longrepr = excinfo
|
||||
elif excinfo.errisinstance(py.test.skip.Exception):
|
||||
outcome = "skipped"
|
||||
longrepr = item._repr_failure_py(excinfo)
|
||||
r = item._repr_failure_py(excinfo, "line").reprcrash
|
||||
longrepr = (str(r.path), r.lineno, r.message)
|
||||
else:
|
||||
outcome = "failed"
|
||||
if call.when == "call":
|
||||
|
@ -189,14 +202,14 @@ class TeardownErrorReport(BaseReport):
|
|||
|
||||
def pytest_make_collect_report(collector):
|
||||
call = CallInfo(collector._memocollect, "memocollect")
|
||||
reason = longrepr = None
|
||||
longrepr = None
|
||||
if not call.excinfo:
|
||||
outcome = "passed"
|
||||
else:
|
||||
if call.excinfo.errisinstance(py.test.skip.Exception):
|
||||
outcome = "skipped"
|
||||
reason = str(call.excinfo.value)
|
||||
longrepr = collector._repr_failure_py(call.excinfo, "line")
|
||||
r = collector._repr_failure_py(call.excinfo, "line").reprcrash
|
||||
longrepr = (str(r.path), r.lineno, r.message)
|
||||
else:
|
||||
outcome = "failed"
|
||||
errorinfo = collector.repr_failure(call.excinfo)
|
||||
|
@ -204,15 +217,14 @@ def pytest_make_collect_report(collector):
|
|||
errorinfo = CollectErrorRepr(errorinfo)
|
||||
longrepr = errorinfo
|
||||
return CollectReport(collector.nodeid, outcome, longrepr,
|
||||
getattr(call, 'result', None), reason)
|
||||
getattr(call, 'result', None))
|
||||
|
||||
class CollectReport(BaseReport):
|
||||
def __init__(self, nodeid, outcome, longrepr, result, reason):
|
||||
def __init__(self, nodeid, outcome, longrepr, result):
|
||||
self.nodeid = nodeid
|
||||
self.outcome = outcome
|
||||
self.longrepr = longrepr
|
||||
self.result = result or []
|
||||
self.reason = reason
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
|
@ -355,6 +367,7 @@ def importorskip(modname, minversion=None):
|
|||
optionally specified 'minversion' - otherwise call py.test.skip()
|
||||
with a message detailing the mismatch.
|
||||
"""
|
||||
__tracebackhide__ = True
|
||||
compile(modname, '', 'eval') # to catch syntaxerrors
|
||||
try:
|
||||
mod = __import__(modname, None, None, ['__doc__'])
|
||||
|
|
|
@ -186,8 +186,8 @@ def cached_eval(config, expr, d):
|
|||
def folded_skips(skipped):
|
||||
d = {}
|
||||
for event in skipped:
|
||||
entry = event.longrepr.reprcrash
|
||||
key = entry.path, entry.lineno, entry.message
|
||||
key = event.longrepr
|
||||
assert len(key) == 3, (event, key)
|
||||
d.setdefault(key, []).append(event)
|
||||
l = []
|
||||
for key, events in d.items():
|
||||
|
|
|
@ -389,7 +389,7 @@ class CollectonlyReporter:
|
|||
msg = report.longrepr.reprcrash.message
|
||||
else:
|
||||
# XXX unify (we have CollectErrorRepr here)
|
||||
msg = str(report.longrepr.longrepr)
|
||||
msg = str(report.longrepr[2])
|
||||
self.outindent("!!! %s !!!" % msg)
|
||||
#self.outindent("!!! error !!!")
|
||||
self._failed.append(report)
|
||||
|
|
|
@ -5,7 +5,7 @@ see http://pytest.org for documentation and details
|
|||
|
||||
(c) Holger Krekel and others, 2004-2010
|
||||
"""
|
||||
__version__ = '2.0.0.dev27'
|
||||
__version__ = '2.0.0.dev28'
|
||||
__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.dev27',
|
||||
version='2.0.0.dev28',
|
||||
url='http://pytest.org',
|
||||
license='MIT license',
|
||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||
|
|
|
@ -344,13 +344,18 @@ def test_exception_printing_skip():
|
|||
|
||||
def test_importorskip():
|
||||
importorskip = py.test.importorskip
|
||||
def f():
|
||||
importorskip("asdlkj")
|
||||
try:
|
||||
sys = importorskip("sys")
|
||||
assert sys == py.std.sys
|
||||
#path = py.test.importorskip("os.path")
|
||||
#assert path == py.std.os.path
|
||||
py.test.raises(py.test.skip.Exception,
|
||||
"py.test.importorskip('alskdj')")
|
||||
excinfo = py.test.raises(py.test.skip.Exception, f)
|
||||
path = py.path.local(excinfo.getrepr().reprcrash.path)
|
||||
# check that importorskip reports the actual call
|
||||
# in this test the test_runner.py file
|
||||
assert path.purebasename == "test_runner"
|
||||
py.test.raises(SyntaxError, "py.test.importorskip('x y z')")
|
||||
py.test.raises(SyntaxError, "py.test.importorskip('x=y')")
|
||||
path = importorskip("py", minversion=".".join(py.__version__))
|
||||
|
|
|
@ -366,11 +366,10 @@ def test_skipif_class(testdir):
|
|||
|
||||
|
||||
def test_skip_reasons_folding():
|
||||
class longrepr:
|
||||
class reprcrash:
|
||||
path = 'xyz'
|
||||
lineno = 3
|
||||
message = "justso"
|
||||
path = 'xyz'
|
||||
lineno = 3
|
||||
message = "justso"
|
||||
longrepr = (path, lineno, message)
|
||||
|
||||
class X:
|
||||
pass
|
||||
|
@ -387,9 +386,9 @@ def test_skip_reasons_folding():
|
|||
assert len(l) == 1
|
||||
num, fspath, lineno, reason = l[0]
|
||||
assert num == 2
|
||||
assert fspath == longrepr.reprcrash.path
|
||||
assert lineno == longrepr.reprcrash.lineno
|
||||
assert reason == longrepr.reprcrash.message
|
||||
assert fspath == path
|
||||
assert lineno == lineno
|
||||
assert reason == message
|
||||
|
||||
def test_skipped_reasons_functional(testdir):
|
||||
testdir.makepyfile(
|
||||
|
|
Loading…
Reference in New Issue