test_ok1/py/test/plugin/pytest_plugintester.py

88 lines
3.1 KiB
Python
Raw Normal View History

"""
plugin with support classes and functions for testing pytest functionality
"""
import py
from py.__.test.plugin import api
class PlugintesterPlugin:
""" test support code for testing pytest plugins. """
def pytest_funcarg__plugintester(self, request):
return PluginTester(request)
class PluginTester:
def __init__(self, request):
self.request = request
def testdir(self):
from pytest_pytester import TmpTestdir
crunner = TmpTestdir(self.request)
self.request.addfinalizer(crunner.finalize)
#
#for colitem in self.request.listchain():
# if isinstance(colitem, py.test.collect.Module) and \
# colitem.name.startswith("pytest_"):
# crunner.plugins.append(colitem.fspath.purebasename)
# break
return crunner
def hookcheck(self, pluginclass):
print "loading and checking", pluginclass
fail = False
pm = py.test._PluginManager()
methods = collectattr(pluginclass)
hooks = collectattr(api.PluginHooks)
getargs = py.std.inspect.getargs
def isgenerichook(name):
return name.startswith("pytest_funcarg__")
while methods:
name, method = methods.popitem()
if isgenerichook(name):
continue
if name not in hooks:
print "found unknown hook: %s" % name
fail = True
else:
hook = hooks[name]
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:
print "argument mismatch:"
print "actual : %s.%s" %(pluginclass.__name__, formatdef(method))
print "required:", formatdef(hook)
fail = True
break
if not fail:
print "matching hook:", formatdef(method)
if fail:
py.test.fail("Plugin API error")
def collectattr(obj, prefixes=("pytest_",)):
methods = {}
for apiname in vars(obj):
for prefix in prefixes:
if apiname.startswith(prefix):
methods[apiname] = getattr(obj, apiname)
return methods
def formatdef(func):
formatargspec = py.std.inspect.formatargspec
getargspec = py.std.inspect.formatargspec
return "%s%s" %(
func.func_name,
py.std.inspect.formatargspec(*py.std.inspect.getargspec(func))
)
# ===============================================================================
# plugin tests
# ===============================================================================
def test_generic(plugintester):
plugintester.hookcheck(PlugintesterPlugin)