properly handle test items that get locally collected but cannot be collected on the remote side (often due to platform reasons)
--HG-- branch : 1.0.x
This commit is contained in:
parent
dcf194ebb8
commit
ad34e50b71
|
@ -1,7 +1,11 @@
|
|||
Changes between 1.0.0b8 and 1.0.0b9
|
||||
=====================================
|
||||
|
||||
* simplified py.test.mark API
|
||||
* dist-testing: properly handle test items that get locally
|
||||
collected but cannot be collected on the remote side - often
|
||||
due to platform/dependency reasons
|
||||
|
||||
* simplified py.test.mark API - see keyword plugin documentation
|
||||
|
||||
* make assert-reinterpretation work better with comparisons not
|
||||
returning bools (reported with numpy from thanks maciej fijalkowski)
|
||||
|
|
|
@ -4,7 +4,6 @@ Collectors and test Items form a tree
|
|||
that is usually built iteratively.
|
||||
"""
|
||||
import py
|
||||
from py.__.test.outcome import Skipped
|
||||
|
||||
def configproperty(name):
|
||||
def fget(self):
|
||||
|
@ -31,6 +30,10 @@ class Node(object):
|
|||
self.config = getattr(parent, 'config', None)
|
||||
self.fspath = getattr(parent, 'fspath', None)
|
||||
|
||||
def _checkcollectable(self):
|
||||
if not hasattr(self, 'fspath'):
|
||||
self.parent._memocollect() # to reraise exception
|
||||
|
||||
#
|
||||
# note to myself: Pickling is uh.
|
||||
#
|
||||
|
@ -44,6 +47,7 @@ class Node(object):
|
|||
except Exception:
|
||||
# seems our parent can't collect us
|
||||
# so let's be somewhat operable
|
||||
# _checkcollectable() is to tell outsiders about the fact
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
self.config = parent.config
|
||||
|
|
|
@ -367,13 +367,21 @@ class TestDSession:
|
|||
assert node.gateway.spec.popen
|
||||
#XXX eq.geteventargs("pytest_sessionfinish")
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_collected_function_causes_remote_skip_at_module_level(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
py.test.importorskip("xyz")
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
# we need to be able to collect test_func locally but not in the subprocess
|
||||
XXX
|
||||
def test_collected_function_causes_remote_skip(testdir):
|
||||
sub = testdir.mkpydir("testing")
|
||||
sub.join("test_module.py").write(py.code.Source("""
|
||||
import py
|
||||
path = py.path.local(%r)
|
||||
if path.check():
|
||||
path.remove()
|
||||
else:
|
||||
py.test.skip("remote skip")
|
||||
def test_func():
|
||||
pass
|
||||
def test_func2():
|
||||
pass
|
||||
""" % str(sub.ensure("somefile"))))
|
||||
result = testdir.runpytest('-v', '--dist=each', '--tx=popen')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*2 skipped*"
|
||||
])
|
||||
|
|
|
@ -124,12 +124,37 @@ class SlaveNode(object):
|
|||
break
|
||||
if isinstance(task, list):
|
||||
for item in task:
|
||||
item.config.hook.pytest_runtest_protocol(item=item)
|
||||
self.run_single(item=item)
|
||||
else:
|
||||
task.config.hook.pytest_runtest_protocol(item=task)
|
||||
self.run_single(item=task)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
er = py.code.ExceptionInfo().getrepr(funcargs=True, showlocals=True)
|
||||
self.sendevent("pytest_internalerror", excrepr=er)
|
||||
raise
|
||||
|
||||
def run_single(self, item):
|
||||
call = CallInfo(item._checkcollectable, 'setup')
|
||||
if call.excinfo:
|
||||
# likely it is not collectable here because of
|
||||
# platform/import-dependency induced skips
|
||||
# XXX somewhat ugly shortcuts - also makes a collection
|
||||
# failure into an ItemTestReport - this might confuse
|
||||
# pytest_runtest_logreport hooks
|
||||
runner = item.config.pluginmanager.getplugin("pytest_runner")
|
||||
rep = runner.pytest_runtest_makereport(item=item, call=call)
|
||||
self.pytest_runtest_logreport(rep)
|
||||
return
|
||||
item.config.hook.pytest_runtest_protocol(item=item)
|
||||
|
||||
class CallInfo:
|
||||
excinfo = None
|
||||
def __init__(self, func, when):
|
||||
self.when = when
|
||||
try:
|
||||
self.result = func()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
self.excinfo = py.code.ExceptionInfo()
|
||||
|
|
|
@ -129,7 +129,12 @@ class TmpTestdir:
|
|||
|
||||
def mkdir(self, name):
|
||||
return self.tmpdir.mkdir(name)
|
||||
|
||||
|
||||
def mkpydir(self, name):
|
||||
p = self.mkdir(name)
|
||||
p.ensure("__init__.py")
|
||||
return p
|
||||
|
||||
def genitems(self, colitems):
|
||||
return list(self.session.genitems(colitems))
|
||||
|
||||
|
|
Loading…
Reference in New Issue