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:
holger krekel 2010-11-13 21:03:28 +01:00
parent 1bc444d5c8
commit 82ba645a2e
8 changed files with 42 additions and 24 deletions

View File

@ -74,17 +74,18 @@ class ResultLog(object):
elif report.failed: elif report.failed:
longrepr = str(report.longrepr) longrepr = str(report.longrepr)
elif report.skipped: elif report.skipped:
longrepr = str(report.longrepr.reprcrash.message) longrepr = str(report.longrepr[2])
self.log_outcome(report, code, longrepr) self.log_outcome(report, code, longrepr)
def pytest_collectreport(self, report): def pytest_collectreport(self, report):
if not report.passed: if not report.passed:
if report.failed: if report.failed:
code = "F" code = "F"
longrepr = str(report.longrepr.reprcrash)
else: else:
assert report.skipped assert report.skipped
code = "S" code = "S"
longrepr = str(report.longrepr.reprcrash) longrepr = "%s:%d: %s" % report.longrepr
self.log_outcome(report, code, longrepr) self.log_outcome(report, code, longrepr)
def pytest_internalerror(self, excrepr): def pytest_internalerror(self, excrepr):

View File

@ -111,9 +111,21 @@ class CallInfo:
status = "result: %r" % (self.result,) status = "result: %r" % (self.result,)
return "<CallInfo when=%r %s>" % (self.when, status) 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): class BaseReport(object):
def toterminal(self, out): def toterminal(self, out):
longrepr = self.longrepr longrepr = self.longrepr
if hasattr(self, 'node'):
out.line(getslaveinfoline(self.node))
if hasattr(longrepr, 'toterminal'): if hasattr(longrepr, 'toterminal'):
longrepr.toterminal(out) longrepr.toterminal(out)
else: else:
@ -140,7 +152,8 @@ def pytest_runtest_makereport(item, call):
longrepr = excinfo longrepr = excinfo
elif excinfo.errisinstance(py.test.skip.Exception): elif excinfo.errisinstance(py.test.skip.Exception):
outcome = "skipped" 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: else:
outcome = "failed" outcome = "failed"
if call.when == "call": if call.when == "call":
@ -189,14 +202,14 @@ class TeardownErrorReport(BaseReport):
def pytest_make_collect_report(collector): def pytest_make_collect_report(collector):
call = CallInfo(collector._memocollect, "memocollect") call = CallInfo(collector._memocollect, "memocollect")
reason = longrepr = None longrepr = None
if not call.excinfo: if not call.excinfo:
outcome = "passed" outcome = "passed"
else: else:
if call.excinfo.errisinstance(py.test.skip.Exception): if call.excinfo.errisinstance(py.test.skip.Exception):
outcome = "skipped" outcome = "skipped"
reason = str(call.excinfo.value) r = collector._repr_failure_py(call.excinfo, "line").reprcrash
longrepr = collector._repr_failure_py(call.excinfo, "line") longrepr = (str(r.path), r.lineno, r.message)
else: else:
outcome = "failed" outcome = "failed"
errorinfo = collector.repr_failure(call.excinfo) errorinfo = collector.repr_failure(call.excinfo)
@ -204,15 +217,14 @@ def pytest_make_collect_report(collector):
errorinfo = CollectErrorRepr(errorinfo) errorinfo = CollectErrorRepr(errorinfo)
longrepr = errorinfo longrepr = errorinfo
return CollectReport(collector.nodeid, outcome, longrepr, return CollectReport(collector.nodeid, outcome, longrepr,
getattr(call, 'result', None), reason) getattr(call, 'result', None))
class CollectReport(BaseReport): class CollectReport(BaseReport):
def __init__(self, nodeid, outcome, longrepr, result, reason): def __init__(self, nodeid, outcome, longrepr, result):
self.nodeid = nodeid self.nodeid = nodeid
self.outcome = outcome self.outcome = outcome
self.longrepr = longrepr self.longrepr = longrepr
self.result = result or [] self.result = result or []
self.reason = reason
@property @property
def location(self): def location(self):
@ -355,6 +367,7 @@ def importorskip(modname, minversion=None):
optionally specified 'minversion' - otherwise call py.test.skip() optionally specified 'minversion' - otherwise call py.test.skip()
with a message detailing the mismatch. with a message detailing the mismatch.
""" """
__tracebackhide__ = True
compile(modname, '', 'eval') # to catch syntaxerrors compile(modname, '', 'eval') # to catch syntaxerrors
try: try:
mod = __import__(modname, None, None, ['__doc__']) mod = __import__(modname, None, None, ['__doc__'])

View File

@ -186,8 +186,8 @@ def cached_eval(config, expr, d):
def folded_skips(skipped): def folded_skips(skipped):
d = {} d = {}
for event in skipped: for event in skipped:
entry = event.longrepr.reprcrash key = event.longrepr
key = entry.path, entry.lineno, entry.message assert len(key) == 3, (event, key)
d.setdefault(key, []).append(event) d.setdefault(key, []).append(event)
l = [] l = []
for key, events in d.items(): for key, events in d.items():

View File

@ -389,7 +389,7 @@ class CollectonlyReporter:
msg = report.longrepr.reprcrash.message msg = report.longrepr.reprcrash.message
else: else:
# XXX unify (we have CollectErrorRepr here) # XXX unify (we have CollectErrorRepr here)
msg = str(report.longrepr.longrepr) msg = str(report.longrepr[2])
self.outindent("!!! %s !!!" % msg) self.outindent("!!! %s !!!" % msg)
#self.outindent("!!! error !!!") #self.outindent("!!! error !!!")
self._failed.append(report) self._failed.append(report)

View File

@ -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.dev27' __version__ = '2.0.0.dev28'
__all__ = ['main'] __all__ = ['main']
from _pytest.core import main, UsageError, _preloadplugins from _pytest.core import main, UsageError, _preloadplugins

View File

@ -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.dev27', version='2.0.0.dev28',
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'],

View File

@ -344,13 +344,18 @@ def test_exception_printing_skip():
def test_importorskip(): def test_importorskip():
importorskip = py.test.importorskip importorskip = py.test.importorskip
def f():
importorskip("asdlkj")
try: try:
sys = importorskip("sys") sys = importorskip("sys")
assert sys == py.std.sys assert sys == py.std.sys
#path = py.test.importorskip("os.path") #path = py.test.importorskip("os.path")
#assert path == py.std.os.path #assert path == py.std.os.path
py.test.raises(py.test.skip.Exception, excinfo = py.test.raises(py.test.skip.Exception, f)
"py.test.importorskip('alskdj')") 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 z')")
py.test.raises(SyntaxError, "py.test.importorskip('x=y')") py.test.raises(SyntaxError, "py.test.importorskip('x=y')")
path = importorskip("py", minversion=".".join(py.__version__)) path = importorskip("py", minversion=".".join(py.__version__))

View File

@ -366,11 +366,10 @@ def test_skipif_class(testdir):
def test_skip_reasons_folding(): def test_skip_reasons_folding():
class longrepr: path = 'xyz'
class reprcrash: lineno = 3
path = 'xyz' message = "justso"
lineno = 3 longrepr = (path, lineno, message)
message = "justso"
class X: class X:
pass pass
@ -387,9 +386,9 @@ def test_skip_reasons_folding():
assert len(l) == 1 assert len(l) == 1
num, fspath, lineno, reason = l[0] num, fspath, lineno, reason = l[0]
assert num == 2 assert num == 2
assert fspath == longrepr.reprcrash.path assert fspath == path
assert lineno == longrepr.reprcrash.lineno assert lineno == lineno
assert reason == longrepr.reprcrash.message assert reason == message
def test_skipped_reasons_functional(testdir): def test_skipped_reasons_functional(testdir):
testdir.makepyfile( testdir.makepyfile(