merge config, pluginmanager, main into one file
--HG-- branch : trunk
This commit is contained in:
parent
6efc6dcb62
commit
6631447161
|
@ -232,7 +232,7 @@ initialisation, command line and configuration hooks
|
||||||
generic "runtest" hooks
|
generic "runtest" hooks
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
Almost runtest related hooks receive a :py:class:`pytest.collect.Item` object.
|
All all runtest related hooks receive a :py:class:`pytest.collect.Item` object.
|
||||||
|
|
||||||
.. autofunction:: pytest_runtest_protocol
|
.. autofunction:: pytest_runtest_protocol
|
||||||
.. autofunction:: pytest_runtest_setup
|
.. autofunction:: pytest_runtest_setup
|
||||||
|
@ -340,13 +340,13 @@ name. Given a filesystem ``fspath`` it is constructed as follows:
|
||||||
Reference of important objects involved in hooks
|
Reference of important objects involved in hooks
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
.. autoclass:: pytest._config.Config
|
.. autoclass:: pytest._core.Config
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. autoclass:: pytest.collect.Item
|
.. autoclass:: pytest.plugin.session.Item
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
|
||||||
.. autoclass:: pytest.collect.Node
|
.. autoclass:: pytest.plugin.session.Node
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. autoclass:: pytest.plugin.runner.CallInfo
|
.. autoclass:: pytest.plugin.runner.CallInfo
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
"""
|
"""
|
||||||
py.test / pytest API for unit and functional testing with Python.
|
py.test / pytest API for unit and functional testing with Python.
|
||||||
|
|
||||||
|
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.0dev0"
|
__version__ = "2.0.0dev0"
|
||||||
|
|
||||||
__all__ = ['collect', 'cmdline', 'config']
|
__all__ = ['config', 'cmdline']
|
||||||
|
|
||||||
import pytest._config
|
from pytest import _core as cmdline
|
||||||
config = pytest._config.Config()
|
from pytest._core import Config
|
||||||
from pytest import main as cmdline
|
config = Config()
|
||||||
|
|
||||||
def __main__():
|
def __main__():
|
||||||
raise SystemExit(cmdline.main())
|
raise SystemExit(cmdline.main())
|
||||||
|
|
|
@ -1,6 +1,25 @@
|
||||||
import py, os
|
import py
|
||||||
from pytest.pluginmanager import PluginManager
|
import sys, os
|
||||||
import optparse
|
|
||||||
|
default_plugins = (
|
||||||
|
"session terminal python runner pdb capture mark skipping tmpdir monkeypatch "
|
||||||
|
"recwarn pastebin unittest helpconfig nose assertion genscript "
|
||||||
|
"junitxml doctest keyword").split()
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
import sys
|
||||||
|
if args is None:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
config = py.test.config
|
||||||
|
config.parse(args)
|
||||||
|
try:
|
||||||
|
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
||||||
|
except config.Error:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
|
||||||
|
exitstatus = 3
|
||||||
|
py.test.config = config.__class__()
|
||||||
|
return exitstatus
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
""" Parser for command line arguments. """
|
""" Parser for command line arguments. """
|
||||||
|
@ -47,7 +66,7 @@ class Parser:
|
||||||
for group in groups:
|
for group in groups:
|
||||||
if group.options:
|
if group.options:
|
||||||
desc = group.description or group.name
|
desc = group.description or group.name
|
||||||
optgroup = optparse.OptionGroup(optparser, desc)
|
optgroup = py.std.optparse.OptionGroup(optparser, desc)
|
||||||
optgroup.add_options(group.options)
|
optgroup.add_options(group.options)
|
||||||
optparser.add_option_group(optgroup)
|
optparser.add_option_group(optgroup)
|
||||||
return optparser.parse_args([str(x) for x in args])
|
return optparser.parse_args([str(x) for x in args])
|
||||||
|
@ -68,11 +87,11 @@ class OptionGroup:
|
||||||
|
|
||||||
def addoption(self, *optnames, **attrs):
|
def addoption(self, *optnames, **attrs):
|
||||||
""" add an option to this group. """
|
""" add an option to this group. """
|
||||||
option = optparse.Option(*optnames, **attrs)
|
option = py.std.optparse.Option(*optnames, **attrs)
|
||||||
self._addoption_instance(option, shortupper=False)
|
self._addoption_instance(option, shortupper=False)
|
||||||
|
|
||||||
def _addoption(self, *optnames, **attrs):
|
def _addoption(self, *optnames, **attrs):
|
||||||
option = optparse.Option(*optnames, **attrs)
|
option = py.std.optparse.Option(*optnames, **attrs)
|
||||||
self._addoption_instance(option, shortupper=True)
|
self._addoption_instance(option, shortupper=True)
|
||||||
|
|
||||||
def _addoption_instance(self, option, shortupper=False):
|
def _addoption_instance(self, option, shortupper=False):
|
||||||
|
@ -85,10 +104,10 @@ class OptionGroup:
|
||||||
self.options.append(option)
|
self.options.append(option)
|
||||||
|
|
||||||
|
|
||||||
class MyOptionParser(optparse.OptionParser):
|
class MyOptionParser(py.std.optparse.OptionParser):
|
||||||
def __init__(self, parser):
|
def __init__(self, parser):
|
||||||
self._parser = parser
|
self._parser = parser
|
||||||
optparse.OptionParser.__init__(self, usage=parser._usage)
|
py.std.optparse.OptionParser.__init__(self, usage=parser._usage)
|
||||||
def format_epilog(self, formatter):
|
def format_epilog(self, formatter):
|
||||||
hints = self._parser.hints
|
hints = self._parser.hints
|
||||||
if hints:
|
if hints:
|
||||||
|
@ -96,6 +115,7 @@ class MyOptionParser(optparse.OptionParser):
|
||||||
s = "\n" + s + "\n"
|
s = "\n" + s + "\n"
|
||||||
return s
|
return s
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
class Conftest(object):
|
class Conftest(object):
|
||||||
""" the single place for accessing values and interacting
|
""" the single place for accessing values and interacting
|
||||||
towards conftest modules from py.test objects.
|
towards conftest modules from py.test objects.
|
||||||
|
@ -386,15 +406,368 @@ class Config(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return self._conftest.rget(name, path)
|
return self._conftest.rget(name, path)
|
||||||
|
|
||||||
#
|
class PluginManager(object):
|
||||||
# helpers
|
def __init__(self):
|
||||||
#
|
from pytest import hookspec
|
||||||
|
self.registry = Registry()
|
||||||
|
self._name2plugin = {}
|
||||||
|
self._hints = []
|
||||||
|
self.hook = HookRelay([hookspec], registry=self.registry)
|
||||||
|
self.register(self)
|
||||||
|
for spec in default_plugins:
|
||||||
|
self.import_plugin(spec)
|
||||||
|
|
||||||
def onpytestaccess():
|
def _getpluginname(self, plugin, name):
|
||||||
# it's enough to have our containing module loaded as
|
if name is None:
|
||||||
# it initializes a per-process config instance
|
if hasattr(plugin, '__name__'):
|
||||||
# which loads default plugins which add to py.test.*
|
name = plugin.__name__.split(".")[-1]
|
||||||
pass
|
else:
|
||||||
|
name = id(plugin)
|
||||||
|
return name
|
||||||
|
|
||||||
|
def register(self, plugin, name=None, prepend=False):
|
||||||
|
assert not self.isregistered(plugin), plugin
|
||||||
|
assert not self.registry.isregistered(plugin), plugin
|
||||||
|
name = self._getpluginname(plugin, name)
|
||||||
|
if name in self._name2plugin:
|
||||||
|
return False
|
||||||
|
self._name2plugin[name] = plugin
|
||||||
|
self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self})
|
||||||
|
self.hook.pytest_plugin_registered(manager=self, plugin=plugin)
|
||||||
|
self.registry.register(plugin, prepend=prepend)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def unregister(self, plugin):
|
||||||
|
self.hook.pytest_plugin_unregistered(plugin=plugin)
|
||||||
|
self.registry.unregister(plugin)
|
||||||
|
for name, value in list(self._name2plugin.items()):
|
||||||
|
if value == plugin:
|
||||||
|
del self._name2plugin[name]
|
||||||
|
|
||||||
|
def isregistered(self, plugin, name=None):
|
||||||
|
if self._getpluginname(plugin, name) in self._name2plugin:
|
||||||
|
return True
|
||||||
|
for val in self._name2plugin.values():
|
||||||
|
if plugin == val:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def addhooks(self, spec):
|
||||||
|
self.hook._addhooks(spec, prefix="pytest_")
|
||||||
|
|
||||||
|
def getplugins(self):
|
||||||
|
return list(self.registry)
|
||||||
|
|
||||||
|
def skipifmissing(self, name):
|
||||||
|
if not self.hasplugin(name):
|
||||||
|
py.test.skip("plugin %r is missing" % name)
|
||||||
|
|
||||||
|
def hasplugin(self, name):
|
||||||
|
try:
|
||||||
|
self.getplugin(name)
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getplugin(self, name):
|
||||||
|
try:
|
||||||
|
return self._name2plugin[name]
|
||||||
|
except KeyError:
|
||||||
|
impname = canonical_importname(name)
|
||||||
|
return self._name2plugin[impname]
|
||||||
|
|
||||||
|
# API for bootstrapping
|
||||||
|
#
|
||||||
|
def _envlist(self, varname):
|
||||||
|
val = py.std.os.environ.get(varname, None)
|
||||||
|
if val is not None:
|
||||||
|
return val.split(',')
|
||||||
|
return ()
|
||||||
|
|
||||||
|
def consider_env(self):
|
||||||
|
for spec in self._envlist("PYTEST_PLUGINS"):
|
||||||
|
self.import_plugin(spec)
|
||||||
|
|
||||||
|
def consider_setuptools_entrypoints(self):
|
||||||
|
try:
|
||||||
|
from pkg_resources import iter_entry_points
|
||||||
|
except ImportError:
|
||||||
|
return # XXX issue a warning
|
||||||
|
for ep in iter_entry_points('pytest11'):
|
||||||
|
name = canonical_importname(ep.name)
|
||||||
|
if name in self._name2plugin:
|
||||||
|
continue
|
||||||
|
plugin = ep.load()
|
||||||
|
self.register(plugin, name=name)
|
||||||
|
|
||||||
|
def consider_preparse(self, args):
|
||||||
|
for opt1,opt2 in zip(args, args[1:]):
|
||||||
|
if opt1 == "-p":
|
||||||
|
self.import_plugin(opt2)
|
||||||
|
|
||||||
|
def consider_conftest(self, conftestmodule):
|
||||||
|
cls = getattr(conftestmodule, 'ConftestPlugin', None)
|
||||||
|
if cls is not None:
|
||||||
|
raise ValueError("%r: 'ConftestPlugins' only existed till 1.0.0b1, "
|
||||||
|
"were removed in 1.0.0b2" % (cls,))
|
||||||
|
if self.register(conftestmodule, name=conftestmodule.__file__):
|
||||||
|
self.consider_module(conftestmodule)
|
||||||
|
|
||||||
|
def consider_module(self, mod):
|
||||||
|
attr = getattr(mod, "pytest_plugins", ())
|
||||||
|
if attr:
|
||||||
|
if not isinstance(attr, (list, tuple)):
|
||||||
|
attr = (attr,)
|
||||||
|
for spec in attr:
|
||||||
|
self.import_plugin(spec)
|
||||||
|
|
||||||
|
def import_plugin(self, spec):
|
||||||
|
assert isinstance(spec, str)
|
||||||
|
modname = canonical_importname(spec)
|
||||||
|
if modname in self._name2plugin:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
mod = importplugin(modname)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except py.test.skip.Exception:
|
||||||
|
e = py.std.sys.exc_info()[1]
|
||||||
|
self._hints.append("skipped plugin %r: %s" %((modname, e.msg)))
|
||||||
|
else:
|
||||||
|
self.register(mod, modname)
|
||||||
|
self.consider_module(mod)
|
||||||
|
|
||||||
|
def pytest_terminal_summary(self, terminalreporter):
|
||||||
|
tw = terminalreporter._tw
|
||||||
|
if terminalreporter.config.option.traceconfig:
|
||||||
|
for hint in self._hints:
|
||||||
|
tw.line("hint: %s" % hint)
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# API for interacting with registered and instantiated plugin objects
|
||||||
|
#
|
||||||
|
#
|
||||||
|
def listattr(self, attrname, plugins=None):
|
||||||
|
return self.registry.listattr(attrname, plugins=plugins)
|
||||||
|
|
||||||
|
def notify_exception(self, excinfo=None):
|
||||||
|
if excinfo is None:
|
||||||
|
excinfo = py.code.ExceptionInfo()
|
||||||
|
excrepr = excinfo.getrepr(funcargs=True, showlocals=True)
|
||||||
|
res = self.hook.pytest_internalerror(excrepr=excrepr)
|
||||||
|
if not py.builtin.any(res):
|
||||||
|
for line in str(excrepr).split("\n"):
|
||||||
|
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
def do_addoption(self, parser):
|
||||||
|
mname = "pytest_addoption"
|
||||||
|
methods = self.registry.listattr(mname, reverse=True)
|
||||||
|
mc = MultiCall(methods, {'parser': parser})
|
||||||
|
mc.execute()
|
||||||
|
|
||||||
|
def _setns(self, obj, dic):
|
||||||
|
for name, value in dic.items():
|
||||||
|
if isinstance(value, dict):
|
||||||
|
mod = getattr(obj, name, None)
|
||||||
|
if mod is None:
|
||||||
|
mod = py.std.types.ModuleType(name)
|
||||||
|
sys.modules['pytest.%s' % name] = mod
|
||||||
|
sys.modules['py.test.%s' % name] = mod
|
||||||
|
mod.__all__ = []
|
||||||
|
setattr(obj, name, mod)
|
||||||
|
self._setns(mod, value)
|
||||||
|
else:
|
||||||
|
#print "setting", name, value, "on", obj
|
||||||
|
setattr(obj, name, value)
|
||||||
|
obj.__all__.append(name)
|
||||||
|
|
||||||
|
def pytest_plugin_registered(self, plugin):
|
||||||
|
dic = self.call_plugin(plugin, "pytest_namespace", {}) or {}
|
||||||
|
if dic:
|
||||||
|
self._setns(py.test, dic)
|
||||||
|
if hasattr(self, '_config'):
|
||||||
|
self.call_plugin(plugin, "pytest_addoption",
|
||||||
|
{'parser': self._config._parser})
|
||||||
|
self.call_plugin(plugin, "pytest_configure",
|
||||||
|
{'config': self._config})
|
||||||
|
|
||||||
|
def call_plugin(self, plugin, methname, kwargs):
|
||||||
|
return MultiCall(
|
||||||
|
methods=self.listattr(methname, plugins=[plugin]),
|
||||||
|
kwargs=kwargs, firstresult=True).execute()
|
||||||
|
|
||||||
|
def do_configure(self, config):
|
||||||
|
assert not hasattr(self, '_config')
|
||||||
|
self._config = config
|
||||||
|
config.hook.pytest_configure(config=self._config)
|
||||||
|
|
||||||
|
def do_unconfigure(self, config):
|
||||||
|
config = self._config
|
||||||
|
del self._config
|
||||||
|
config.hook.pytest_unconfigure(config=config)
|
||||||
|
config.pluginmanager.unregister(self)
|
||||||
|
|
||||||
|
def canonical_importname(name):
|
||||||
|
name = name.lower()
|
||||||
|
modprefix = "pytest_"
|
||||||
|
if not name.startswith(modprefix):
|
||||||
|
name = modprefix + name
|
||||||
|
return name
|
||||||
|
|
||||||
|
def importplugin(importspec):
|
||||||
|
#print "importing", importspec
|
||||||
|
try:
|
||||||
|
return __import__(importspec)
|
||||||
|
except ImportError:
|
||||||
|
e = py.std.sys.exc_info()[1]
|
||||||
|
if str(e).find(importspec) == -1:
|
||||||
|
raise
|
||||||
|
name = importspec
|
||||||
|
try:
|
||||||
|
if name.startswith("pytest_"):
|
||||||
|
name = importspec[7:]
|
||||||
|
return __import__("pytest.plugin.%s" %(name), None, None, '__doc__')
|
||||||
|
except ImportError:
|
||||||
|
e = py.std.sys.exc_info()[1]
|
||||||
|
if str(e).find(name) == -1:
|
||||||
|
raise
|
||||||
|
# show the original exception, not the failing internal one
|
||||||
|
return __import__(importspec)
|
||||||
|
|
||||||
|
|
||||||
|
class MultiCall:
|
||||||
|
""" execute a call into multiple python functions/methods. """
|
||||||
|
|
||||||
|
def __init__(self, methods, kwargs, firstresult=False):
|
||||||
|
self.methods = methods[:]
|
||||||
|
self.kwargs = kwargs.copy()
|
||||||
|
self.kwargs['__multicall__'] = self
|
||||||
|
self.results = []
|
||||||
|
self.firstresult = firstresult
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
status = "%d results, %d meths" % (len(self.results), len(self.methods))
|
||||||
|
return "<MultiCall %s, kwargs=%r>" %(status, self.kwargs)
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
while self.methods:
|
||||||
|
method = self.methods.pop()
|
||||||
|
kwargs = self.getkwargs(method)
|
||||||
|
res = method(**kwargs)
|
||||||
|
if res is not None:
|
||||||
|
self.results.append(res)
|
||||||
|
if self.firstresult:
|
||||||
|
return res
|
||||||
|
if not self.firstresult:
|
||||||
|
return self.results
|
||||||
|
|
||||||
|
def getkwargs(self, method):
|
||||||
|
kwargs = {}
|
||||||
|
for argname in varnames(method):
|
||||||
|
try:
|
||||||
|
kwargs[argname] = self.kwargs[argname]
|
||||||
|
except KeyError:
|
||||||
|
pass # might be optional param
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def varnames(func):
|
||||||
|
import inspect
|
||||||
|
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||||
|
func = getattr(func, '__call__', func)
|
||||||
|
ismethod = inspect.ismethod(func)
|
||||||
|
rawcode = py.code.getrawcode(func)
|
||||||
|
try:
|
||||||
|
return rawcode.co_varnames[ismethod:]
|
||||||
|
except AttributeError:
|
||||||
|
return ()
|
||||||
|
|
||||||
|
class Registry:
|
||||||
|
"""
|
||||||
|
Manage Plugins: register/unregister call calls to plugins.
|
||||||
|
"""
|
||||||
|
def __init__(self, plugins=None):
|
||||||
|
if plugins is None:
|
||||||
|
plugins = []
|
||||||
|
self._plugins = plugins
|
||||||
|
|
||||||
|
def register(self, plugin, prepend=False):
|
||||||
|
assert not isinstance(plugin, str)
|
||||||
|
assert not plugin in self._plugins
|
||||||
|
if not prepend:
|
||||||
|
self._plugins.append(plugin)
|
||||||
|
else:
|
||||||
|
self._plugins.insert(0, plugin)
|
||||||
|
|
||||||
|
def unregister(self, plugin):
|
||||||
|
self._plugins.remove(plugin)
|
||||||
|
|
||||||
|
def isregistered(self, plugin):
|
||||||
|
return plugin in self._plugins
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._plugins)
|
||||||
|
|
||||||
|
def listattr(self, attrname, plugins=None, reverse=False):
|
||||||
|
l = []
|
||||||
|
if plugins is None:
|
||||||
|
plugins = self._plugins
|
||||||
|
for plugin in plugins:
|
||||||
|
try:
|
||||||
|
l.append(getattr(plugin, attrname))
|
||||||
|
except AttributeError:
|
||||||
|
continue
|
||||||
|
if reverse:
|
||||||
|
l.reverse()
|
||||||
|
return l
|
||||||
|
|
||||||
|
class HookRelay:
|
||||||
|
def __init__(self, hookspecs, registry, prefix="pytest_"):
|
||||||
|
if not isinstance(hookspecs, list):
|
||||||
|
hookspecs = [hookspecs]
|
||||||
|
self._hookspecs = []
|
||||||
|
self._registry = registry
|
||||||
|
for hookspec in hookspecs:
|
||||||
|
self._addhooks(hookspec, prefix)
|
||||||
|
|
||||||
|
def _addhooks(self, hookspecs, prefix):
|
||||||
|
self._hookspecs.append(hookspecs)
|
||||||
|
added = False
|
||||||
|
for name, method in vars(hookspecs).items():
|
||||||
|
if name.startswith(prefix):
|
||||||
|
if not method.__doc__:
|
||||||
|
raise ValueError("docstring required for hook %r, in %r"
|
||||||
|
% (method, hookspecs))
|
||||||
|
firstresult = getattr(method, 'firstresult', False)
|
||||||
|
hc = HookCaller(self, name, firstresult=firstresult)
|
||||||
|
setattr(self, name, hc)
|
||||||
|
added = True
|
||||||
|
#print ("setting new hook", name)
|
||||||
|
if not added:
|
||||||
|
raise ValueError("did not find new %r hooks in %r" %(
|
||||||
|
prefix, hookspecs,))
|
||||||
|
|
||||||
|
|
||||||
|
def _performcall(self, name, multicall):
|
||||||
|
return multicall.execute()
|
||||||
|
|
||||||
|
class HookCaller:
|
||||||
|
def __init__(self, hookrelay, name, firstresult):
|
||||||
|
self.hookrelay = hookrelay
|
||||||
|
self.name = name
|
||||||
|
self.firstresult = firstresult
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<HookCaller %r>" %(self.name,)
|
||||||
|
|
||||||
|
def __call__(self, **kwargs):
|
||||||
|
methods = self.hookrelay._registry.listattr(self.name)
|
||||||
|
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
|
||||||
|
return self.hookrelay._performcall(self.name, mc)
|
||||||
|
|
||||||
|
def pcall(self, plugins, **kwargs):
|
||||||
|
methods = self.hookrelay._registry.listattr(self.name, plugins=plugins)
|
||||||
|
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
|
||||||
|
return self.hookrelay._performcall(self.name, mc)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
"""
|
""" hook specifications for pytest plugins, invoked from _core.py and builtin plugins. """
|
||||||
hook specifications for py.test plugins
|
|
||||||
"""
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Initialization
|
# Initialization
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
__all__ = []
|
|
||||||
import py, pytest
|
|
||||||
|
|
||||||
def main(args=None):
|
|
||||||
import sys
|
|
||||||
if args is None:
|
|
||||||
args = sys.argv[1:]
|
|
||||||
config = py.test.config
|
|
||||||
config.parse(args)
|
|
||||||
try:
|
|
||||||
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
|
||||||
except config.Error:
|
|
||||||
e = sys.exc_info()[1]
|
|
||||||
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
|
|
||||||
exitstatus = 3
|
|
||||||
py.test.config = config.__class__()
|
|
||||||
return exitstatus
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import py
|
import py
|
||||||
|
|
||||||
from pytest.pluginmanager import HookRelay
|
from pytest._core import HookRelay
|
||||||
|
|
||||||
def pytest_funcarg___pytest(request):
|
def pytest_funcarg___pytest(request):
|
||||||
return PytestArg(request)
|
return PytestArg(request)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import re
|
||||||
import inspect
|
import inspect
|
||||||
import time
|
import time
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from pytest._config import Config as pytestConfig
|
from pytest._core import Config as pytestConfig
|
||||||
from pytest.plugin.session import Collection
|
from pytest.plugin.session import Collection
|
||||||
from py.builtin import print_
|
from py.builtin import print_
|
||||||
|
|
||||||
|
@ -222,7 +222,6 @@ class TmpTestdir:
|
||||||
""" this is used from tests that want to re-invoke parse(). """
|
""" this is used from tests that want to re-invoke parse(). """
|
||||||
if not args:
|
if not args:
|
||||||
args = [self.tmpdir]
|
args = [self.tmpdir]
|
||||||
from pytest import _config
|
|
||||||
oldconfig = py.test.config
|
oldconfig = py.test.config
|
||||||
try:
|
try:
|
||||||
c = py.test.config = pytestConfig()
|
c = py.test.config = pytestConfig()
|
||||||
|
|
|
@ -1,381 +0,0 @@
|
||||||
"""
|
|
||||||
managing loading and interacting with pytest plugins.
|
|
||||||
"""
|
|
||||||
import py
|
|
||||||
import sys
|
|
||||||
|
|
||||||
default_plugins = (
|
|
||||||
"session terminal python runner pdb capture mark skipping tmpdir monkeypatch "
|
|
||||||
"recwarn pastebin unittest helpconfig nose assertion genscript "
|
|
||||||
"junitxml doctest keyword").split()
|
|
||||||
|
|
||||||
def check_old_use(mod, modname):
|
|
||||||
clsname = modname[len('pytest_'):].capitalize() + "Plugin"
|
|
||||||
assert not hasattr(mod, clsname), (mod, clsname)
|
|
||||||
|
|
||||||
class PluginManager(object):
|
|
||||||
def __init__(self):
|
|
||||||
from pytest import hookspec
|
|
||||||
self.registry = Registry()
|
|
||||||
self._name2plugin = {}
|
|
||||||
self._hints = []
|
|
||||||
self.hook = HookRelay([hookspec], registry=self.registry)
|
|
||||||
self.register(self)
|
|
||||||
for spec in default_plugins:
|
|
||||||
self.import_plugin(spec)
|
|
||||||
|
|
||||||
def _getpluginname(self, plugin, name):
|
|
||||||
if name is None:
|
|
||||||
if hasattr(plugin, '__name__'):
|
|
||||||
name = plugin.__name__.split(".")[-1]
|
|
||||||
else:
|
|
||||||
name = id(plugin)
|
|
||||||
return name
|
|
||||||
|
|
||||||
def register(self, plugin, name=None, prepend=False):
|
|
||||||
assert not self.isregistered(plugin), plugin
|
|
||||||
assert not self.registry.isregistered(plugin), plugin
|
|
||||||
name = self._getpluginname(plugin, name)
|
|
||||||
if name in self._name2plugin:
|
|
||||||
return False
|
|
||||||
self._name2plugin[name] = plugin
|
|
||||||
self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self})
|
|
||||||
self.hook.pytest_plugin_registered(manager=self, plugin=plugin)
|
|
||||||
self.registry.register(plugin, prepend=prepend)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def unregister(self, plugin):
|
|
||||||
self.hook.pytest_plugin_unregistered(plugin=plugin)
|
|
||||||
self.registry.unregister(plugin)
|
|
||||||
for name, value in list(self._name2plugin.items()):
|
|
||||||
if value == plugin:
|
|
||||||
del self._name2plugin[name]
|
|
||||||
|
|
||||||
def isregistered(self, plugin, name=None):
|
|
||||||
if self._getpluginname(plugin, name) in self._name2plugin:
|
|
||||||
return True
|
|
||||||
for val in self._name2plugin.values():
|
|
||||||
if plugin == val:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def addhooks(self, spec):
|
|
||||||
self.hook._addhooks(spec, prefix="pytest_")
|
|
||||||
|
|
||||||
def getplugins(self):
|
|
||||||
return list(self.registry)
|
|
||||||
|
|
||||||
def skipifmissing(self, name):
|
|
||||||
if not self.hasplugin(name):
|
|
||||||
py.test.skip("plugin %r is missing" % name)
|
|
||||||
|
|
||||||
def hasplugin(self, name):
|
|
||||||
try:
|
|
||||||
self.getplugin(name)
|
|
||||||
except KeyError:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def getplugin(self, name):
|
|
||||||
try:
|
|
||||||
return self._name2plugin[name]
|
|
||||||
except KeyError:
|
|
||||||
impname = canonical_importname(name)
|
|
||||||
return self._name2plugin[impname]
|
|
||||||
|
|
||||||
# API for bootstrapping
|
|
||||||
#
|
|
||||||
def _envlist(self, varname):
|
|
||||||
val = py.std.os.environ.get(varname, None)
|
|
||||||
if val is not None:
|
|
||||||
return val.split(',')
|
|
||||||
return ()
|
|
||||||
|
|
||||||
def consider_env(self):
|
|
||||||
for spec in self._envlist("PYTEST_PLUGINS"):
|
|
||||||
self.import_plugin(spec)
|
|
||||||
|
|
||||||
def consider_setuptools_entrypoints(self):
|
|
||||||
try:
|
|
||||||
from pkg_resources import iter_entry_points
|
|
||||||
except ImportError:
|
|
||||||
return # XXX issue a warning
|
|
||||||
for ep in iter_entry_points('pytest11'):
|
|
||||||
name = canonical_importname(ep.name)
|
|
||||||
if name in self._name2plugin:
|
|
||||||
continue
|
|
||||||
plugin = ep.load()
|
|
||||||
self.register(plugin, name=name)
|
|
||||||
|
|
||||||
def consider_preparse(self, args):
|
|
||||||
for opt1,opt2 in zip(args, args[1:]):
|
|
||||||
if opt1 == "-p":
|
|
||||||
self.import_plugin(opt2)
|
|
||||||
|
|
||||||
def consider_conftest(self, conftestmodule):
|
|
||||||
cls = getattr(conftestmodule, 'ConftestPlugin', None)
|
|
||||||
if cls is not None:
|
|
||||||
raise ValueError("%r: 'ConftestPlugins' only existed till 1.0.0b1, "
|
|
||||||
"were removed in 1.0.0b2" % (cls,))
|
|
||||||
if self.register(conftestmodule, name=conftestmodule.__file__):
|
|
||||||
self.consider_module(conftestmodule)
|
|
||||||
|
|
||||||
def consider_module(self, mod):
|
|
||||||
attr = getattr(mod, "pytest_plugins", ())
|
|
||||||
if attr:
|
|
||||||
if not isinstance(attr, (list, tuple)):
|
|
||||||
attr = (attr,)
|
|
||||||
for spec in attr:
|
|
||||||
self.import_plugin(spec)
|
|
||||||
|
|
||||||
def import_plugin(self, spec):
|
|
||||||
assert isinstance(spec, str)
|
|
||||||
modname = canonical_importname(spec)
|
|
||||||
if modname in self._name2plugin:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
mod = importplugin(modname)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except py.test.skip.Exception:
|
|
||||||
e = py.std.sys.exc_info()[1]
|
|
||||||
self._hints.append("skipped plugin %r: %s" %((modname, e.msg)))
|
|
||||||
else:
|
|
||||||
check_old_use(mod, modname)
|
|
||||||
self.register(mod, modname)
|
|
||||||
self.consider_module(mod)
|
|
||||||
|
|
||||||
def pytest_terminal_summary(self, terminalreporter):
|
|
||||||
tw = terminalreporter._tw
|
|
||||||
if terminalreporter.config.option.traceconfig:
|
|
||||||
for hint in self._hints:
|
|
||||||
tw.line("hint: %s" % hint)
|
|
||||||
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# API for interacting with registered and instantiated plugin objects
|
|
||||||
#
|
|
||||||
#
|
|
||||||
def listattr(self, attrname, plugins=None):
|
|
||||||
return self.registry.listattr(attrname, plugins=plugins)
|
|
||||||
|
|
||||||
def notify_exception(self, excinfo=None):
|
|
||||||
if excinfo is None:
|
|
||||||
excinfo = py.code.ExceptionInfo()
|
|
||||||
excrepr = excinfo.getrepr(funcargs=True, showlocals=True)
|
|
||||||
res = self.hook.pytest_internalerror(excrepr=excrepr)
|
|
||||||
if not py.builtin.any(res):
|
|
||||||
for line in str(excrepr).split("\n"):
|
|
||||||
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
def do_addoption(self, parser):
|
|
||||||
mname = "pytest_addoption"
|
|
||||||
methods = self.registry.listattr(mname, reverse=True)
|
|
||||||
mc = MultiCall(methods, {'parser': parser})
|
|
||||||
mc.execute()
|
|
||||||
|
|
||||||
def _setns(self, obj, dic):
|
|
||||||
for name, value in dic.items():
|
|
||||||
if isinstance(value, dict):
|
|
||||||
mod = getattr(obj, name, None)
|
|
||||||
if mod is None:
|
|
||||||
mod = py.std.types.ModuleType(name)
|
|
||||||
sys.modules['pytest.%s' % name] = mod
|
|
||||||
sys.modules['py.test.%s' % name] = mod
|
|
||||||
mod.__all__ = []
|
|
||||||
setattr(obj, name, mod)
|
|
||||||
self._setns(mod, value)
|
|
||||||
else:
|
|
||||||
#print "setting", name, value, "on", obj
|
|
||||||
setattr(obj, name, value)
|
|
||||||
obj.__all__.append(name)
|
|
||||||
|
|
||||||
def pytest_plugin_registered(self, plugin):
|
|
||||||
dic = self.call_plugin(plugin, "pytest_namespace", {}) or {}
|
|
||||||
if dic:
|
|
||||||
self._setns(py.test, dic)
|
|
||||||
if hasattr(self, '_config'):
|
|
||||||
self.call_plugin(plugin, "pytest_addoption",
|
|
||||||
{'parser': self._config._parser})
|
|
||||||
self.call_plugin(plugin, "pytest_configure",
|
|
||||||
{'config': self._config})
|
|
||||||
|
|
||||||
def call_plugin(self, plugin, methname, kwargs):
|
|
||||||
return MultiCall(
|
|
||||||
methods=self.listattr(methname, plugins=[plugin]),
|
|
||||||
kwargs=kwargs, firstresult=True).execute()
|
|
||||||
|
|
||||||
def do_configure(self, config):
|
|
||||||
assert not hasattr(self, '_config')
|
|
||||||
self._config = config
|
|
||||||
config.hook.pytest_configure(config=self._config)
|
|
||||||
|
|
||||||
def do_unconfigure(self, config):
|
|
||||||
config = self._config
|
|
||||||
del self._config
|
|
||||||
config.hook.pytest_unconfigure(config=config)
|
|
||||||
config.pluginmanager.unregister(self)
|
|
||||||
|
|
||||||
def canonical_importname(name):
|
|
||||||
name = name.lower()
|
|
||||||
modprefix = "pytest_"
|
|
||||||
if not name.startswith(modprefix):
|
|
||||||
name = modprefix + name
|
|
||||||
return name
|
|
||||||
|
|
||||||
def importplugin(importspec):
|
|
||||||
#print "importing", importspec
|
|
||||||
try:
|
|
||||||
return __import__(importspec)
|
|
||||||
except ImportError:
|
|
||||||
e = py.std.sys.exc_info()[1]
|
|
||||||
if str(e).find(importspec) == -1:
|
|
||||||
raise
|
|
||||||
name = importspec
|
|
||||||
try:
|
|
||||||
if name.startswith("pytest_"):
|
|
||||||
name = importspec[7:]
|
|
||||||
return __import__("pytest.plugin.%s" %(name), None, None, '__doc__')
|
|
||||||
except ImportError:
|
|
||||||
e = py.std.sys.exc_info()[1]
|
|
||||||
if str(e).find(name) == -1:
|
|
||||||
raise
|
|
||||||
# show the original exception, not the failing internal one
|
|
||||||
return __import__(importspec)
|
|
||||||
|
|
||||||
|
|
||||||
class MultiCall:
|
|
||||||
""" execute a call into multiple python functions/methods. """
|
|
||||||
|
|
||||||
def __init__(self, methods, kwargs, firstresult=False):
|
|
||||||
self.methods = methods[:]
|
|
||||||
self.kwargs = kwargs.copy()
|
|
||||||
self.kwargs['__multicall__'] = self
|
|
||||||
self.results = []
|
|
||||||
self.firstresult = firstresult
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
status = "%d results, %d meths" % (len(self.results), len(self.methods))
|
|
||||||
return "<MultiCall %s, kwargs=%r>" %(status, self.kwargs)
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
while self.methods:
|
|
||||||
method = self.methods.pop()
|
|
||||||
kwargs = self.getkwargs(method)
|
|
||||||
res = method(**kwargs)
|
|
||||||
if res is not None:
|
|
||||||
self.results.append(res)
|
|
||||||
if self.firstresult:
|
|
||||||
return res
|
|
||||||
if not self.firstresult:
|
|
||||||
return self.results
|
|
||||||
|
|
||||||
def getkwargs(self, method):
|
|
||||||
kwargs = {}
|
|
||||||
for argname in varnames(method):
|
|
||||||
try:
|
|
||||||
kwargs[argname] = self.kwargs[argname]
|
|
||||||
except KeyError:
|
|
||||||
pass # might be optional param
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def varnames(func):
|
|
||||||
import inspect
|
|
||||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
|
||||||
func = getattr(func, '__call__', func)
|
|
||||||
ismethod = inspect.ismethod(func)
|
|
||||||
rawcode = py.code.getrawcode(func)
|
|
||||||
try:
|
|
||||||
return rawcode.co_varnames[ismethod:]
|
|
||||||
except AttributeError:
|
|
||||||
return ()
|
|
||||||
|
|
||||||
class Registry:
|
|
||||||
"""
|
|
||||||
Manage Plugins: register/unregister call calls to plugins.
|
|
||||||
"""
|
|
||||||
def __init__(self, plugins=None):
|
|
||||||
if plugins is None:
|
|
||||||
plugins = []
|
|
||||||
self._plugins = plugins
|
|
||||||
|
|
||||||
def register(self, plugin, prepend=False):
|
|
||||||
assert not isinstance(plugin, str)
|
|
||||||
assert not plugin in self._plugins
|
|
||||||
if not prepend:
|
|
||||||
self._plugins.append(plugin)
|
|
||||||
else:
|
|
||||||
self._plugins.insert(0, plugin)
|
|
||||||
|
|
||||||
def unregister(self, plugin):
|
|
||||||
self._plugins.remove(plugin)
|
|
||||||
|
|
||||||
def isregistered(self, plugin):
|
|
||||||
return plugin in self._plugins
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self._plugins)
|
|
||||||
|
|
||||||
def listattr(self, attrname, plugins=None, reverse=False):
|
|
||||||
l = []
|
|
||||||
if plugins is None:
|
|
||||||
plugins = self._plugins
|
|
||||||
for plugin in plugins:
|
|
||||||
try:
|
|
||||||
l.append(getattr(plugin, attrname))
|
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
if reverse:
|
|
||||||
l.reverse()
|
|
||||||
return l
|
|
||||||
|
|
||||||
class HookRelay:
|
|
||||||
def __init__(self, hookspecs, registry, prefix="pytest_"):
|
|
||||||
if not isinstance(hookspecs, list):
|
|
||||||
hookspecs = [hookspecs]
|
|
||||||
self._hookspecs = []
|
|
||||||
self._registry = registry
|
|
||||||
for hookspec in hookspecs:
|
|
||||||
self._addhooks(hookspec, prefix)
|
|
||||||
|
|
||||||
def _addhooks(self, hookspecs, prefix):
|
|
||||||
self._hookspecs.append(hookspecs)
|
|
||||||
added = False
|
|
||||||
for name, method in vars(hookspecs).items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
if not method.__doc__:
|
|
||||||
raise ValueError("docstring required for hook %r, in %r"
|
|
||||||
% (method, hookspecs))
|
|
||||||
firstresult = getattr(method, 'firstresult', False)
|
|
||||||
hc = HookCaller(self, name, firstresult=firstresult)
|
|
||||||
setattr(self, name, hc)
|
|
||||||
added = True
|
|
||||||
#print ("setting new hook", name)
|
|
||||||
if not added:
|
|
||||||
raise ValueError("did not find new %r hooks in %r" %(
|
|
||||||
prefix, hookspecs,))
|
|
||||||
|
|
||||||
|
|
||||||
def _performcall(self, name, multicall):
|
|
||||||
return multicall.execute()
|
|
||||||
|
|
||||||
class HookCaller:
|
|
||||||
def __init__(self, hookrelay, name, firstresult):
|
|
||||||
self.hookrelay = hookrelay
|
|
||||||
self.name = name
|
|
||||||
self.firstresult = firstresult
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<HookCaller %r>" %(self.name,)
|
|
||||||
|
|
||||||
def __call__(self, **kwargs):
|
|
||||||
methods = self.hookrelay._registry.listattr(self.name)
|
|
||||||
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
|
|
||||||
return self.hookrelay._performcall(self.name, mc)
|
|
||||||
|
|
||||||
def pcall(self, plugins, **kwargs):
|
|
||||||
methods = self.hookrelay._registry.listattr(self.name, plugins=plugins)
|
|
||||||
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
|
|
||||||
return self.hookrelay._performcall(self.name, mc)
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import py
|
||||||
pytest_plugins = "pytester"
|
pytest_plugins = "pytester"
|
||||||
import pytest.plugin
|
import pytest.plugin
|
||||||
plugindir = py.path.local(pytest.plugin.__file__).dirpath()
|
plugindir = py.path.local(pytest.plugin.__file__).dirpath()
|
||||||
from pytest.pluginmanager import default_plugins
|
from pytest._core import default_plugins
|
||||||
|
|
||||||
def pytest_collect_file(path, parent):
|
def pytest_collect_file(path, parent):
|
||||||
if path.basename.startswith("pytest_") and path.ext == ".py":
|
if path.basename.startswith("pytest_") and path.ext == ".py":
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import py
|
import py
|
||||||
import os, sys
|
import os, sys
|
||||||
from pytest.plugin._pytest import HookRecorder
|
from pytest.plugin._pytest import HookRecorder
|
||||||
from pytest.pluginmanager import Registry
|
from pytest._core import Registry
|
||||||
|
|
||||||
def test_hookrecorder_basic():
|
def test_hookrecorder_basic():
|
||||||
rec = HookRecorder(Registry())
|
rec = HookRecorder(Registry())
|
||||||
|
@ -29,7 +29,7 @@ def test_hookrecorder_basic_no_args_hook():
|
||||||
def test_functional(testdir, linecomp):
|
def test_functional(testdir, linecomp):
|
||||||
reprec = testdir.inline_runsource("""
|
reprec = testdir.inline_runsource("""
|
||||||
import py
|
import py
|
||||||
from pytest.pluginmanager import HookRelay, Registry
|
from pytest._core import HookRelay, Registry
|
||||||
pytest_plugins="_pytest"
|
pytest_plugins="_pytest"
|
||||||
def test_func(_pytest):
|
def test_func(_pytest):
|
||||||
class ApiClass:
|
class ApiClass:
|
||||||
|
|
|
@ -2,7 +2,7 @@ import py
|
||||||
import os
|
import os
|
||||||
from pytest.plugin.resultlog import generic_path, ResultLog, \
|
from pytest.plugin.resultlog import generic_path, ResultLog, \
|
||||||
pytest_configure, pytest_unconfigure
|
pytest_configure, pytest_unconfigure
|
||||||
from pytest.collect import Node, Item, FSCollector
|
from pytest.plugin.session import Node, Item, FSCollector
|
||||||
|
|
||||||
def test_generic_path(testdir):
|
def test_generic_path(testdir):
|
||||||
from pytest.plugin.session import Collection
|
from pytest.plugin.session import Collection
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import py
|
import py
|
||||||
from pytest._config import Conftest
|
from pytest._core import Conftest
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if "basedir" in metafunc.funcargnames:
|
if "basedir" in metafunc.funcargnames:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import py
|
import py
|
||||||
from pytest import _config as parseopt
|
from pytest import main as parseopt
|
||||||
|
|
||||||
class TestParser:
|
class TestParser:
|
||||||
def test_init(self, capsys):
|
def test_init(self, capsys):
|
||||||
|
@ -42,7 +42,7 @@ class TestParser:
|
||||||
group = parseopt.OptionGroup("hello")
|
group = parseopt.OptionGroup("hello")
|
||||||
group.addoption("--option1", action="store_true")
|
group.addoption("--option1", action="store_true")
|
||||||
assert len(group.options) == 1
|
assert len(group.options) == 1
|
||||||
assert isinstance(group.options[0], parseopt.optparse.Option)
|
assert isinstance(group.options[0], py.std.optparse.Option)
|
||||||
|
|
||||||
def test_group_shortopt_lowercase(self):
|
def test_group_shortopt_lowercase(self):
|
||||||
parser = parseopt.Parser()
|
parser = parseopt.Parser()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import py, os
|
import py, os
|
||||||
from pytest.pluginmanager import PluginManager, canonical_importname
|
from pytest._core import PluginManager, canonical_importname
|
||||||
from pytest.pluginmanager import Registry, MultiCall, HookRelay, varnames
|
from pytest._core import Registry, MultiCall, HookRelay, varnames
|
||||||
|
|
||||||
|
|
||||||
class TestBootstrapping:
|
class TestBootstrapping:
|
||||||
|
@ -232,7 +232,6 @@ class TestBootstrapping:
|
||||||
class TestPytestPluginInteractions:
|
class TestPytestPluginInteractions:
|
||||||
|
|
||||||
def test_addhooks_conftestplugin(self, testdir):
|
def test_addhooks_conftestplugin(self, testdir):
|
||||||
from pytest._config import Config
|
|
||||||
newhooks = testdir.makepyfile(newhooks="""
|
newhooks = testdir.makepyfile(newhooks="""
|
||||||
def pytest_myhook(xyz):
|
def pytest_myhook(xyz):
|
||||||
"new hook"
|
"new hook"
|
||||||
|
@ -245,7 +244,7 @@ class TestPytestPluginInteractions:
|
||||||
def pytest_myhook(xyz):
|
def pytest_myhook(xyz):
|
||||||
return xyz + 1
|
return xyz + 1
|
||||||
""")
|
""")
|
||||||
config = Config()
|
config = testdir.Config()
|
||||||
config._conftest.importconftest(conf)
|
config._conftest.importconftest(conf)
|
||||||
print(config.pluginmanager.getplugins())
|
print(config.pluginmanager.getplugins())
|
||||||
res = config.hook.pytest_myhook(xyz=10)
|
res = config.hook.pytest_myhook(xyz=10)
|
||||||
|
@ -283,12 +282,11 @@ class TestPytestPluginInteractions:
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_do_option_conftestplugin(self, testdir):
|
def test_do_option_conftestplugin(self, testdir):
|
||||||
from pytest._config import Config
|
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
parser.addoption('--test123', action="store_true")
|
parser.addoption('--test123', action="store_true")
|
||||||
""")
|
""")
|
||||||
config = Config()
|
config = testdir.Config()
|
||||||
config._conftest.importconftest(p)
|
config._conftest.importconftest(p)
|
||||||
print(config.pluginmanager.getplugins())
|
print(config.pluginmanager.getplugins())
|
||||||
config.parse([])
|
config.parse([])
|
||||||
|
@ -321,8 +319,7 @@ class TestPytestPluginInteractions:
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_do_option_postinitialize(self, testdir):
|
def test_do_option_postinitialize(self, testdir):
|
||||||
from pytest._config import Config
|
config = testdir.Config()
|
||||||
config = Config()
|
|
||||||
config.parse([])
|
config.parse([])
|
||||||
config.pluginmanager.do_configure(config=config)
|
config.pluginmanager.do_configure(config=config)
|
||||||
assert not hasattr(config.option, 'test123')
|
assert not hasattr(config.option, 'test123')
|
||||||
|
|
Loading…
Reference in New Issue