some more separation of core pluginmanager from pytest specific functionality.
Idea is to have the PluginManager be re-useable from other projects at some point.
This commit is contained in:
parent
d946299b0a
commit
4b709037ab
|
@ -2,6 +2,87 @@
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import sys, os
|
import sys, os
|
||||||
|
from _pytest import hookspec # the extension point definitions
|
||||||
|
from _pytest.core import PluginManager
|
||||||
|
|
||||||
|
# pytest startup
|
||||||
|
|
||||||
|
def main(args=None, plugins=None):
|
||||||
|
""" return exit code, after performing an in-process test run.
|
||||||
|
|
||||||
|
:arg args: list of command line arguments.
|
||||||
|
|
||||||
|
:arg plugins: list of plugin objects to be auto-registered during
|
||||||
|
initialization.
|
||||||
|
"""
|
||||||
|
config = _prepareconfig(args, plugins)
|
||||||
|
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
||||||
|
return exitstatus
|
||||||
|
|
||||||
|
class cmdline: # compatibility namespace
|
||||||
|
main = staticmethod(main)
|
||||||
|
|
||||||
|
class UsageError(Exception):
|
||||||
|
""" error in py.test usage or invocation"""
|
||||||
|
|
||||||
|
_preinit = []
|
||||||
|
|
||||||
|
default_plugins = (
|
||||||
|
"mark main terminal runner python pdb unittest capture skipping "
|
||||||
|
"tmpdir monkeypatch recwarn pastebin helpconfig nose assertion genscript "
|
||||||
|
"junitxml resultlog doctest").split()
|
||||||
|
|
||||||
|
def _preloadplugins():
|
||||||
|
assert not _preinit
|
||||||
|
_preinit.append(get_plugin_manager())
|
||||||
|
|
||||||
|
def get_plugin_manager():
|
||||||
|
if _preinit:
|
||||||
|
return _preinit.pop(0)
|
||||||
|
# subsequent calls to main will create a fresh instance
|
||||||
|
pluginmanager = PytestPluginManager()
|
||||||
|
pluginmanager.config = config = Config(pluginmanager) # XXX attr needed?
|
||||||
|
for spec in default_plugins:
|
||||||
|
pluginmanager.import_plugin(spec)
|
||||||
|
return pluginmanager
|
||||||
|
|
||||||
|
def _prepareconfig(args=None, plugins=None):
|
||||||
|
if args is None:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
elif isinstance(args, py.path.local):
|
||||||
|
args = [str(args)]
|
||||||
|
elif not isinstance(args, (tuple, list)):
|
||||||
|
if not isinstance(args, str):
|
||||||
|
raise ValueError("not a string or argument list: %r" % (args,))
|
||||||
|
args = py.std.shlex.split(args)
|
||||||
|
pluginmanager = get_plugin_manager()
|
||||||
|
if plugins:
|
||||||
|
for plugin in plugins:
|
||||||
|
pluginmanager.register(plugin)
|
||||||
|
return pluginmanager.hook.pytest_cmdline_parse(
|
||||||
|
pluginmanager=pluginmanager, args=args)
|
||||||
|
|
||||||
|
class PytestPluginManager(PluginManager):
|
||||||
|
def __init__(self, hookspecs=[hookspec]):
|
||||||
|
super(PytestPluginManager, self).__init__(hookspecs=hookspecs)
|
||||||
|
self.register(self)
|
||||||
|
if os.environ.get('PYTEST_DEBUG'):
|
||||||
|
err = sys.stderr
|
||||||
|
encoding = getattr(err, 'encoding', 'utf8')
|
||||||
|
try:
|
||||||
|
err = py.io.dupfile(err, encoding=encoding)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.trace.root.setwriter(err.write)
|
||||||
|
|
||||||
|
def pytest_configure(self, config):
|
||||||
|
config.addinivalue_line("markers",
|
||||||
|
"tryfirst: mark a hook implementation function such that the "
|
||||||
|
"plugin machinery will try to call it first/as early as possible.")
|
||||||
|
config.addinivalue_line("markers",
|
||||||
|
"trylast: mark a hook implementation function such that the "
|
||||||
|
"plugin machinery will try to call it last/as late as possible.")
|
||||||
|
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
""" Parser for command line arguments and ini-file values. """
|
""" Parser for command line arguments and ini-file values. """
|
||||||
|
@ -494,10 +575,15 @@ class Config(object):
|
||||||
self._opt2dest = {}
|
self._opt2dest = {}
|
||||||
self._cleanup = []
|
self._cleanup = []
|
||||||
self.pluginmanager.register(self, "pytestconfig")
|
self.pluginmanager.register(self, "pytestconfig")
|
||||||
|
self.pluginmanager.set_register_callback(self._register_plugin)
|
||||||
self._configured = False
|
self._configured = False
|
||||||
|
|
||||||
def pytest_plugin_registered(self, plugin):
|
def _register_plugin(self, plugin, name):
|
||||||
call_plugin = self.pluginmanager.call_plugin
|
call_plugin = self.pluginmanager.call_plugin
|
||||||
|
call_plugin(plugin, "pytest_addhooks",
|
||||||
|
{'pluginmanager': self.pluginmanager})
|
||||||
|
self.hook.pytest_plugin_registered(plugin=plugin,
|
||||||
|
manager=self.pluginmanager)
|
||||||
dic = call_plugin(plugin, "pytest_namespace", {}) or {}
|
dic = call_plugin(plugin, "pytest_namespace", {}) or {}
|
||||||
if dic:
|
if dic:
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -527,10 +613,26 @@ class Config(object):
|
||||||
fin = config._cleanup.pop()
|
fin = config._cleanup.pop()
|
||||||
fin()
|
fin()
|
||||||
|
|
||||||
|
def notify_exception(self, excinfo, option=None):
|
||||||
|
if option and option.fulltrace:
|
||||||
|
style = "long"
|
||||||
|
else:
|
||||||
|
style = "native"
|
||||||
|
excrepr = excinfo.getrepr(funcargs=True,
|
||||||
|
showlocals=getattr(option, 'showlocals', False),
|
||||||
|
style=style,
|
||||||
|
)
|
||||||
|
res = self.hook.pytest_internalerror(excrepr=excrepr,
|
||||||
|
excinfo=excinfo)
|
||||||
|
if not py.builtin.any(res):
|
||||||
|
for line in str(excrepr).split("\n"):
|
||||||
|
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fromdictargs(cls, option_dict, args):
|
def fromdictargs(cls, option_dict, args):
|
||||||
""" constructor useable for subprocesses. """
|
""" constructor useable for subprocesses. """
|
||||||
from _pytest.core import get_plugin_manager
|
|
||||||
pluginmanager = get_plugin_manager()
|
pluginmanager = get_plugin_manager()
|
||||||
config = pluginmanager.config
|
config = pluginmanager.config
|
||||||
# XXX slightly crude way to initialize capturing
|
# XXX slightly crude way to initialize capturing
|
||||||
|
|
110
_pytest/core.py
110
_pytest/core.py
|
@ -4,17 +4,10 @@ pytest PluginManager, basic initialization and tracing.
|
||||||
import sys, os
|
import sys, os
|
||||||
import inspect
|
import inspect
|
||||||
import py
|
import py
|
||||||
from _pytest import hookspec # the extension point definitions
|
|
||||||
from _pytest.config import Config
|
|
||||||
|
|
||||||
assert py.__version__.split(".")[:2] >= ['1', '4'], ("installation problem: "
|
assert py.__version__.split(".")[:2] >= ['1', '4'], ("installation problem: "
|
||||||
"%s is too old, remove or upgrade 'py'" % (py.__version__))
|
"%s is too old, remove or upgrade 'py'" % (py.__version__))
|
||||||
|
|
||||||
default_plugins = (
|
|
||||||
"mark main terminal runner python pdb unittest capture skipping "
|
|
||||||
"tmpdir monkeypatch recwarn pastebin helpconfig nose assertion genscript "
|
|
||||||
"junitxml resultlog doctest").split()
|
|
||||||
|
|
||||||
class TagTracer:
|
class TagTracer:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._tag2proc = {}
|
self._tag2proc = {}
|
||||||
|
@ -73,7 +66,7 @@ class TagTracerSub:
|
||||||
return self.__class__(self.root, self.tags + (name,))
|
return self.__class__(self.root, self.tags + (name,))
|
||||||
|
|
||||||
class PluginManager(object):
|
class PluginManager(object):
|
||||||
def __init__(self, load=False):
|
def __init__(self, hookspecs=None):
|
||||||
self._name2plugin = {}
|
self._name2plugin = {}
|
||||||
self._listattrcache = {}
|
self._listattrcache = {}
|
||||||
self._plugins = []
|
self._plugins = []
|
||||||
|
@ -81,20 +74,11 @@ class PluginManager(object):
|
||||||
self.trace = TagTracer().get("pluginmanage")
|
self.trace = TagTracer().get("pluginmanage")
|
||||||
self._plugin_distinfo = []
|
self._plugin_distinfo = []
|
||||||
self._shutdown = []
|
self._shutdown = []
|
||||||
if os.environ.get('PYTEST_DEBUG'):
|
self.hook = HookRelay(hookspecs or [], pm=self)
|
||||||
err = sys.stderr
|
|
||||||
encoding = getattr(err, 'encoding', 'utf8')
|
def set_register_callback(self, callback):
|
||||||
try:
|
assert not hasattr(self, "_registercallback")
|
||||||
err = py.io.dupfile(err, encoding=encoding)
|
self._registercallback = callback
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
self.trace.root.setwriter(err.write)
|
|
||||||
self.hook = HookRelay([hookspec], pm=self)
|
|
||||||
self.register(self)
|
|
||||||
self.config = Config(self) # XXX unclear if the attr is needed
|
|
||||||
if load:
|
|
||||||
for spec in default_plugins:
|
|
||||||
self.import_plugin(spec)
|
|
||||||
|
|
||||||
def register(self, plugin, name=None, prepend=False):
|
def register(self, plugin, name=None, prepend=False):
|
||||||
if self._name2plugin.get(name, None) == -1:
|
if self._name2plugin.get(name, None) == -1:
|
||||||
|
@ -105,8 +89,9 @@ class PluginManager(object):
|
||||||
name, plugin, self._name2plugin))
|
name, plugin, self._name2plugin))
|
||||||
#self.trace("registering", name, plugin)
|
#self.trace("registering", name, plugin)
|
||||||
self._name2plugin[name] = plugin
|
self._name2plugin[name] = plugin
|
||||||
self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self})
|
reg = getattr(self, "_registercallback", None)
|
||||||
self.hook.pytest_plugin_registered(manager=self, plugin=plugin)
|
if reg is not None:
|
||||||
|
reg(plugin, name)
|
||||||
if not prepend:
|
if not prepend:
|
||||||
self._plugins.append(plugin)
|
self._plugins.append(plugin)
|
||||||
else:
|
else:
|
||||||
|
@ -139,8 +124,8 @@ class PluginManager(object):
|
||||||
if plugin == val:
|
if plugin == val:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def addhooks(self, spec):
|
def addhooks(self, spec, prefix="pytest_"):
|
||||||
self.hook._addhooks(spec, prefix="pytest_")
|
self.hook._addhooks(spec, prefix=prefix)
|
||||||
|
|
||||||
def getplugins(self):
|
def getplugins(self):
|
||||||
return list(self._plugins)
|
return list(self._plugins)
|
||||||
|
@ -240,36 +225,6 @@ class PluginManager(object):
|
||||||
self.register(mod, modname)
|
self.register(mod, modname)
|
||||||
self.consider_module(mod)
|
self.consider_module(mod)
|
||||||
|
|
||||||
def pytest_configure(self, config):
|
|
||||||
config.addinivalue_line("markers",
|
|
||||||
"tryfirst: mark a hook implementation function such that the "
|
|
||||||
"plugin machinery will try to call it first/as early as possible.")
|
|
||||||
config.addinivalue_line("markers",
|
|
||||||
"trylast: mark a hook implementation function such that the "
|
|
||||||
"plugin machinery will try to call it last/as late as possible.")
|
|
||||||
|
|
||||||
def pytest_terminal_summary(self, terminalreporter):
|
|
||||||
tw = terminalreporter._tw
|
|
||||||
if terminalreporter.config.option.traceconfig:
|
|
||||||
for hint in self._hints:
|
|
||||||
tw.line("hint: %s" % hint)
|
|
||||||
|
|
||||||
def notify_exception(self, excinfo, option=None):
|
|
||||||
if option and option.fulltrace:
|
|
||||||
style = "long"
|
|
||||||
else:
|
|
||||||
style = "native"
|
|
||||||
excrepr = excinfo.getrepr(funcargs=True,
|
|
||||||
showlocals=getattr(option, 'showlocals', False),
|
|
||||||
style=style,
|
|
||||||
)
|
|
||||||
res = self.hook.pytest_internalerror(excrepr=excrepr,
|
|
||||||
excinfo=excinfo)
|
|
||||||
if not py.builtin.any(res):
|
|
||||||
for line in str(excrepr).split("\n"):
|
|
||||||
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
def listattr(self, attrname, plugins=None):
|
def listattr(self, attrname, plugins=None):
|
||||||
if plugins is None:
|
if plugins is None:
|
||||||
plugins = self._plugins
|
plugins = self._plugins
|
||||||
|
@ -424,46 +379,3 @@ class HookCaller:
|
||||||
self.trace.root.indent -= 1
|
self.trace.root.indent -= 1
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_preinit = []
|
|
||||||
|
|
||||||
def _preloadplugins():
|
|
||||||
assert not _preinit
|
|
||||||
_preinit.append(PluginManager(load=True))
|
|
||||||
|
|
||||||
def get_plugin_manager():
|
|
||||||
if _preinit:
|
|
||||||
return _preinit.pop(0)
|
|
||||||
else: # subsequent calls to main will create a fresh instance
|
|
||||||
return PluginManager(load=True)
|
|
||||||
|
|
||||||
def _prepareconfig(args=None, plugins=None):
|
|
||||||
if args is None:
|
|
||||||
args = sys.argv[1:]
|
|
||||||
elif isinstance(args, py.path.local):
|
|
||||||
args = [str(args)]
|
|
||||||
elif not isinstance(args, (tuple, list)):
|
|
||||||
if not isinstance(args, str):
|
|
||||||
raise ValueError("not a string or argument list: %r" % (args,))
|
|
||||||
args = py.std.shlex.split(args)
|
|
||||||
pluginmanager = get_plugin_manager()
|
|
||||||
if plugins:
|
|
||||||
for plugin in plugins:
|
|
||||||
pluginmanager.register(plugin)
|
|
||||||
return pluginmanager.hook.pytest_cmdline_parse(
|
|
||||||
pluginmanager=pluginmanager, args=args)
|
|
||||||
|
|
||||||
def main(args=None, plugins=None):
|
|
||||||
""" return exit code, after performing an in-process test run.
|
|
||||||
|
|
||||||
:arg args: list of command line arguments.
|
|
||||||
|
|
||||||
:arg plugins: list of plugin objects to be auto-registered during
|
|
||||||
initialization.
|
|
||||||
"""
|
|
||||||
config = _prepareconfig(args, plugins)
|
|
||||||
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
|
||||||
return exitstatus
|
|
||||||
|
|
||||||
class UsageError(Exception):
|
|
||||||
""" error in py.test usage or invocation"""
|
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ def wrap_session(config, doit):
|
||||||
session.exitstatus = EXIT_INTERRUPTED
|
session.exitstatus = EXIT_INTERRUPTED
|
||||||
except:
|
except:
|
||||||
excinfo = py.code.ExceptionInfo()
|
excinfo = py.code.ExceptionInfo()
|
||||||
config.pluginmanager.notify_exception(excinfo, config.option)
|
config.notify_exception(excinfo, config.option)
|
||||||
session.exitstatus = EXIT_INTERNALERROR
|
session.exitstatus = EXIT_INTERNALERROR
|
||||||
if excinfo.errisinstance(SystemExit):
|
if excinfo.errisinstance(SystemExit):
|
||||||
sys.stderr.write("mainloop: caught Spurious SystemExit!\n")
|
sys.stderr.write("mainloop: caught Spurious SystemExit!\n")
|
||||||
|
|
|
@ -375,8 +375,8 @@ class TmpTestdir:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
args.append("--basetemp=%s" % self.tmpdir.dirpath('basetemp'))
|
args.append("--basetemp=%s" % self.tmpdir.dirpath('basetemp'))
|
||||||
import _pytest.core
|
import _pytest.config
|
||||||
config = _pytest.core._prepareconfig(args, self.plugins)
|
config = _pytest.config._prepareconfig(args, self.plugins)
|
||||||
# we don't know what the test will do with this half-setup config
|
# we don't know what the test will do with this half-setup config
|
||||||
# object and thus we make sure it gets unconfigured properly in any
|
# object and thus we make sure it gets unconfigured properly in any
|
||||||
# case (otherwise capturing could still be active, for example)
|
# case (otherwise capturing could still be active, for example)
|
||||||
|
|
|
@ -342,6 +342,7 @@ class TerminalReporter:
|
||||||
if exitstatus in (0, 1, 2, 4):
|
if exitstatus in (0, 1, 2, 4):
|
||||||
self.summary_errors()
|
self.summary_errors()
|
||||||
self.summary_failures()
|
self.summary_failures()
|
||||||
|
self.summary_hints()
|
||||||
self.config.hook.pytest_terminal_summary(terminalreporter=self)
|
self.config.hook.pytest_terminal_summary(terminalreporter=self)
|
||||||
if exitstatus == 2:
|
if exitstatus == 2:
|
||||||
self._report_keyboardinterrupt()
|
self._report_keyboardinterrupt()
|
||||||
|
@ -407,6 +408,11 @@ class TerminalReporter:
|
||||||
l.append(x)
|
l.append(x)
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
def summary_hints(self):
|
||||||
|
if self.config.option.traceconfig:
|
||||||
|
for hint in self.config.pluginmanager._hints:
|
||||||
|
self._tw.line("hint: %s" % hint)
|
||||||
|
|
||||||
def summary_failures(self):
|
def summary_failures(self):
|
||||||
if self.config.option.tbstyle != "no":
|
if self.config.option.tbstyle != "no":
|
||||||
reports = self.getreports('failed')
|
reports = self.getreports('failed')
|
||||||
|
|
14
pytest.py
14
pytest.py
|
@ -8,9 +8,11 @@ if __name__ == '__main__': # if run as a script or by 'python -m pytest'
|
||||||
# we trigger the below "else" condition by the following import
|
# we trigger the below "else" condition by the following import
|
||||||
import pytest
|
import pytest
|
||||||
raise SystemExit(pytest.main())
|
raise SystemExit(pytest.main())
|
||||||
else:
|
|
||||||
# we are simply imported
|
# else we are imported
|
||||||
from _pytest.core import main, UsageError, _preloadplugins
|
|
||||||
from _pytest import core as cmdline
|
from _pytest.config import main, UsageError, _preloadplugins, cmdline
|
||||||
from _pytest import __version__
|
from _pytest import __version__
|
||||||
_preloadplugins() # to populate pytest.* namespace so help(pytest) works
|
|
||||||
|
_preloadplugins() # to populate pytest.* namespace so help(pytest) works
|
||||||
|
|
||||||
|
|
|
@ -320,3 +320,18 @@ def test_cmdline_processargs_simple(testdir):
|
||||||
def test_toolongargs_issue224(testdir):
|
def test_toolongargs_issue224(testdir):
|
||||||
result = testdir.runpytest("-m", "hello" * 500)
|
result = testdir.runpytest("-m", "hello" * 500)
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
|
def test_notify_exception(testdir, capfd):
|
||||||
|
config = testdir.parseconfig()
|
||||||
|
excinfo = pytest.raises(ValueError, "raise ValueError(1)")
|
||||||
|
config.notify_exception(excinfo)
|
||||||
|
out, err = capfd.readouterr()
|
||||||
|
assert "ValueError" in err
|
||||||
|
class A:
|
||||||
|
def pytest_internalerror(self, excrepr):
|
||||||
|
return True
|
||||||
|
config.pluginmanager.register(A())
|
||||||
|
config.notify_exception(excinfo)
|
||||||
|
out, err = capfd.readouterr()
|
||||||
|
assert not err
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pytest, py, os
|
import pytest, py, os
|
||||||
from _pytest.core import PluginManager
|
from _pytest.core import PluginManager
|
||||||
from _pytest.core import MultiCall, HookRelay, varnames
|
from _pytest.core import MultiCall, HookRelay, varnames
|
||||||
|
from _pytest.config import get_plugin_manager
|
||||||
|
|
||||||
|
|
||||||
class TestBootstrapping:
|
class TestBootstrapping:
|
||||||
|
@ -149,7 +150,7 @@ class TestBootstrapping:
|
||||||
mod = py.std.types.ModuleType("x")
|
mod = py.std.types.ModuleType("x")
|
||||||
mod.pytest_plugins = "pytest_a"
|
mod.pytest_plugins = "pytest_a"
|
||||||
aplugin = testdir.makepyfile(pytest_a="#")
|
aplugin = testdir.makepyfile(pytest_a="#")
|
||||||
pluginmanager = PluginManager()
|
pluginmanager = get_plugin_manager()
|
||||||
reprec = testdir.getreportrecorder(pluginmanager)
|
reprec = testdir.getreportrecorder(pluginmanager)
|
||||||
#syspath.prepend(aplugin.dirpath())
|
#syspath.prepend(aplugin.dirpath())
|
||||||
py.std.sys.path.insert(0, str(aplugin.dirpath()))
|
py.std.sys.path.insert(0, str(aplugin.dirpath()))
|
||||||
|
@ -224,36 +225,21 @@ class TestBootstrapping:
|
||||||
assert pp.isregistered(mod)
|
assert pp.isregistered(mod)
|
||||||
|
|
||||||
def test_register_mismatch_method(self):
|
def test_register_mismatch_method(self):
|
||||||
pp = PluginManager(load=True)
|
pp = get_plugin_manager()
|
||||||
class hello:
|
class hello:
|
||||||
def pytest_gurgel(self):
|
def pytest_gurgel(self):
|
||||||
pass
|
pass
|
||||||
pytest.raises(Exception, "pp.register(hello())")
|
pytest.raises(Exception, "pp.register(hello())")
|
||||||
|
|
||||||
def test_register_mismatch_arg(self):
|
def test_register_mismatch_arg(self):
|
||||||
pp = PluginManager(load=True)
|
pp = get_plugin_manager()
|
||||||
class hello:
|
class hello:
|
||||||
def pytest_configure(self, asd):
|
def pytest_configure(self, asd):
|
||||||
pass
|
pass
|
||||||
excinfo = pytest.raises(Exception, "pp.register(hello())")
|
excinfo = pytest.raises(Exception, "pp.register(hello())")
|
||||||
|
|
||||||
|
|
||||||
def test_notify_exception(self, capfd):
|
|
||||||
pp = PluginManager()
|
|
||||||
excinfo = pytest.raises(ValueError, "raise ValueError(1)")
|
|
||||||
pp.notify_exception(excinfo)
|
|
||||||
out, err = capfd.readouterr()
|
|
||||||
assert "ValueError" in err
|
|
||||||
class A:
|
|
||||||
def pytest_internalerror(self, excrepr):
|
|
||||||
return True
|
|
||||||
pp.register(A())
|
|
||||||
pp.notify_exception(excinfo)
|
|
||||||
out, err = capfd.readouterr()
|
|
||||||
assert not err
|
|
||||||
|
|
||||||
def test_register(self):
|
def test_register(self):
|
||||||
pm = PluginManager(load=False)
|
pm = get_plugin_manager()
|
||||||
class MyPlugin:
|
class MyPlugin:
|
||||||
pass
|
pass
|
||||||
my = MyPlugin()
|
my = MyPlugin()
|
||||||
|
@ -261,13 +247,13 @@ class TestBootstrapping:
|
||||||
assert pm.getplugins()
|
assert pm.getplugins()
|
||||||
my2 = MyPlugin()
|
my2 = MyPlugin()
|
||||||
pm.register(my2)
|
pm.register(my2)
|
||||||
assert pm.getplugins()[2:] == [my, my2]
|
assert pm.getplugins()[-2:] == [my, my2]
|
||||||
|
|
||||||
assert pm.isregistered(my)
|
assert pm.isregistered(my)
|
||||||
assert pm.isregistered(my2)
|
assert pm.isregistered(my2)
|
||||||
pm.unregister(my)
|
pm.unregister(my)
|
||||||
assert not pm.isregistered(my)
|
assert not pm.isregistered(my)
|
||||||
assert pm.getplugins()[2:] == [my2]
|
assert pm.getplugins()[-1:] == [my2]
|
||||||
|
|
||||||
def test_listattr(self):
|
def test_listattr(self):
|
||||||
plugins = PluginManager()
|
plugins = PluginManager()
|
||||||
|
@ -284,7 +270,7 @@ class TestBootstrapping:
|
||||||
assert l == [41, 42, 43]
|
assert l == [41, 42, 43]
|
||||||
|
|
||||||
def test_hook_tracing(self):
|
def test_hook_tracing(self):
|
||||||
pm = PluginManager()
|
pm = get_plugin_manager()
|
||||||
saveindent = []
|
saveindent = []
|
||||||
class api1:
|
class api1:
|
||||||
x = 41
|
x = 41
|
||||||
|
@ -319,7 +305,7 @@ class TestPytestPluginInteractions:
|
||||||
def pytest_myhook(xyz):
|
def pytest_myhook(xyz):
|
||||||
return xyz + 1
|
return xyz + 1
|
||||||
""")
|
""")
|
||||||
config = PluginManager(load=True).config
|
config = get_plugin_manager().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)
|
||||||
|
|
|
@ -104,7 +104,7 @@ def test_functional(testdir, linecomp):
|
||||||
def test_func(_pytest):
|
def test_func(_pytest):
|
||||||
class ApiClass:
|
class ApiClass:
|
||||||
def pytest_xyz(self, arg): "x"
|
def pytest_xyz(self, arg): "x"
|
||||||
hook = HookRelay([ApiClass], PluginManager(load=False))
|
hook = HookRelay([ApiClass], PluginManager())
|
||||||
rec = _pytest.gethookrecorder(hook)
|
rec = _pytest.gethookrecorder(hook)
|
||||||
class Plugin:
|
class Plugin:
|
||||||
def pytest_xyz(self, arg):
|
def pytest_xyz(self, arg):
|
||||||
|
|
Loading…
Reference in New Issue