* refactor plugin support to work directly with
modules, no classes required anymore. * call funcarg hook if defined on class --HG-- branch : trunk
This commit is contained in:
parent
4035fa6326
commit
191d02aef2
|
@ -3,13 +3,7 @@ pytest_plugins = '_pytest doctest pytester'.split()
|
|||
rsyncdirs = ['../doc']
|
||||
|
||||
import py
|
||||
class PylibTestconfigPlugin:
|
||||
def pytest_funcarg__specssh(self, request):
|
||||
return getspecssh(request.config)
|
||||
def pytest_funcarg__specsocket(self, request):
|
||||
return getsocketspec(request.config)
|
||||
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("pylib", "py lib testing options")
|
||||
group.addoption('--sshhost',
|
||||
action="store", dest="sshhost", default=None,
|
||||
|
@ -21,7 +15,11 @@ class PylibTestconfigPlugin:
|
|||
action="store_true", dest="runslowtests", default=False,
|
||||
help=("run slow tests"))
|
||||
|
||||
ConftestPlugin = PylibTestconfigPlugin
|
||||
def pytest_funcarg__specssh(request):
|
||||
return getspecssh(request.config)
|
||||
def pytest_funcarg__specsocket(request):
|
||||
return getsocketspec(request.config)
|
||||
|
||||
|
||||
# configuration information for tests
|
||||
def getgspecs(config=None):
|
||||
|
|
|
@ -78,12 +78,15 @@ class FuncargRequest:
|
|||
self.function = pyfuncitem.obj
|
||||
self.module = pyfuncitem._getparent(py.test.collect.Module).obj
|
||||
self.cls = getattr(self.function, 'im_class', None)
|
||||
self.instance = getattr(self.function, 'im_self', None)
|
||||
self.config = pyfuncitem.config
|
||||
self.fspath = pyfuncitem.fspath
|
||||
if hasattr(pyfuncitem, '_requestparam'):
|
||||
self.param = pyfuncitem._requestparam
|
||||
self._plugins = self.config.pluginmanager.getplugins()
|
||||
self._plugins.append(self.module)
|
||||
if self.instance is not None:
|
||||
self._plugins.append(self.instance)
|
||||
self._provider = self.config.pluginmanager.listattr(
|
||||
plugins=self._plugins,
|
||||
attrname=self._argprefix + str(argname)
|
||||
|
@ -126,7 +129,7 @@ class FuncargRequest:
|
|||
def _raiselookupfailed(self):
|
||||
available = []
|
||||
for plugin in self._plugins:
|
||||
for name in vars(plugin.__class__):
|
||||
for name in vars(plugin):
|
||||
if name.startswith(self._argprefix):
|
||||
name = name[len(self._argprefix):]
|
||||
if name not in available:
|
||||
|
|
|
@ -2,9 +2,23 @@ import py
|
|||
|
||||
pytest_plugins = "pytester", "plugintester"
|
||||
|
||||
class ConftestPlugin:
|
||||
def pytest_collect_file(self, path, parent):
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.basename.startswith("pytest_") and path.ext == ".py":
|
||||
mod = parent.Module(path, parent=parent)
|
||||
return mod
|
||||
|
||||
# decorate testdir to contain plugin under test
|
||||
def pytest_funcarg__testdir(request):
|
||||
testdir = request.call_next_provider()
|
||||
#for obj in (request.cls, request.module):
|
||||
# if hasattr(obj, 'testplugin'):
|
||||
# testdir.plugins.append(obj.testplugin)
|
||||
# break
|
||||
#else:
|
||||
basename = request.module.__name__.split(".")[-1]
|
||||
if basename.startswith("pytest_"):
|
||||
testdir.plugins.append(vars(request.module))
|
||||
else:
|
||||
pass # raise ValueError("need better support code")
|
||||
return testdir
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import py
|
||||
|
||||
class _pytestPlugin:
|
||||
def pytest_funcarg___pytest(self, request):
|
||||
def pytest_funcarg___pytest(request):
|
||||
return PytestArg(request)
|
||||
|
||||
class PytestArg:
|
||||
|
@ -97,7 +96,7 @@ class CallRecorder:
|
|||
return l
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(_pytestPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_callrecorder_basic():
|
||||
comregistry = py._com.Registry()
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import py
|
||||
|
||||
class DefaultPlugin:
|
||||
""" Plugin implementing defaults and general options. """
|
||||
|
||||
def pytest_itemrun(self, item, pdb=None):
|
||||
import py
|
||||
|
||||
def pytest_itemrun(item, pdb=None):
|
||||
from py.__.test.runner import basic_run_report, forked_run_report
|
||||
if item.config.option.boxed:
|
||||
runner = forked_run_report
|
||||
|
@ -13,19 +12,19 @@ class DefaultPlugin:
|
|||
item.config.hook.pytest_itemtestreport(rep=report)
|
||||
return True
|
||||
|
||||
def pytest_item_makereport(self, item, excinfo, when, outerr):
|
||||
def pytest_item_makereport(item, excinfo, when, outerr):
|
||||
from py.__.test import runner
|
||||
return runner.ItemTestReport(item, excinfo, when, outerr)
|
||||
|
||||
def pytest_item_runtest_finished(self, item, excinfo, outerr):
|
||||
def pytest_item_runtest_finished(item, excinfo, outerr):
|
||||
from py.__.test import runner
|
||||
rep = runner.ItemTestReport(item, excinfo, "execute", outerr)
|
||||
item.config.hook.pytest_itemtestreport(rep=rep)
|
||||
|
||||
def pytest_pyfunc_call(self, pyfuncitem, args, kwargs):
|
||||
def pytest_pyfunc_call(pyfuncitem, args, kwargs):
|
||||
pyfuncitem.obj(*args, **kwargs)
|
||||
|
||||
def pytest_collect_file(self, path, parent):
|
||||
def pytest_collect_file(path, parent):
|
||||
ext = path.ext
|
||||
pb = path.purebasename
|
||||
if pb.startswith("test_") or pb.endswith("_test") or \
|
||||
|
@ -33,7 +32,7 @@ class DefaultPlugin:
|
|||
if ext == ".py":
|
||||
return parent.Module(path, parent=parent)
|
||||
|
||||
def pytest_collect_recurse(self, path, parent):
|
||||
def pytest_collect_recurse(path, parent):
|
||||
#excludelist = parent._config.getvalue_pathlist('dir_exclude', path)
|
||||
#if excludelist and path in excludelist:
|
||||
# return
|
||||
|
@ -46,7 +45,7 @@ class DefaultPlugin:
|
|||
return False
|
||||
return True
|
||||
|
||||
def pytest_collect_directory(self, path, parent):
|
||||
def pytest_collect_directory(path, parent):
|
||||
# XXX reconsider the following comment
|
||||
# not use parent.Directory here as we generally
|
||||
# want dir/conftest.py to be able to
|
||||
|
@ -54,10 +53,10 @@ class DefaultPlugin:
|
|||
Directory = parent.config.getvalue('Directory', path)
|
||||
return Directory(path, parent=parent)
|
||||
|
||||
def pytest_report_iteminfo(self, item):
|
||||
def pytest_report_iteminfo(item):
|
||||
return item.reportinfo()
|
||||
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("general", "test collection and failure interaction options")
|
||||
group._addoption('-v', '--verbose', action="count",
|
||||
dest="verbose", default=0, help="increase verbosity."),
|
||||
|
@ -140,12 +139,12 @@ class DefaultPlugin:
|
|||
group.addoption('--rsyncdir', action="append", default=[], metavar="dir1",
|
||||
help="add directory for rsyncing to remote tx nodes.")
|
||||
|
||||
def pytest_configure(self, config):
|
||||
self.fixoptions(config)
|
||||
self.setsession(config)
|
||||
self.loadplugins(config)
|
||||
def pytest_configure(config):
|
||||
fixoptions(config)
|
||||
setsession(config)
|
||||
loadplugins(config)
|
||||
|
||||
def fixoptions(self, config):
|
||||
def fixoptions(config):
|
||||
if config.option.numprocesses:
|
||||
config.option.dist = "load"
|
||||
config.option.tx = ['popen'] * int(config.option.numprocesses)
|
||||
|
@ -157,12 +156,12 @@ class DefaultPlugin:
|
|||
if config.option.dist != "no":
|
||||
raise config.Error("--pdb incomptaible with distributing tests.")
|
||||
|
||||
def loadplugins(self, config):
|
||||
def loadplugins(config):
|
||||
for name in config.getvalue("plugin"):
|
||||
print "importing", name
|
||||
config.pluginmanager.import_plugin(name)
|
||||
|
||||
def setsession(self, config):
|
||||
def setsession(config):
|
||||
val = config.getvalue
|
||||
if val("collectonly"):
|
||||
from py.__.test.session import Session
|
||||
|
@ -190,7 +189,7 @@ def test_implied_different_sessions(tmpdir):
|
|||
assert x('-f') == 'LooponfailingSession'
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(DefaultPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_plugin_specify(testdir):
|
||||
testdir.chdir()
|
||||
|
@ -253,14 +252,10 @@ def test_dist_options(testdir):
|
|||
assert config.option.dist == "load"
|
||||
|
||||
def test_pytest_report_iteminfo():
|
||||
plugin = DefaultPlugin()
|
||||
|
||||
class FakeItem(object):
|
||||
|
||||
def reportinfo(self):
|
||||
return "-reportinfo-"
|
||||
|
||||
res = plugin.pytest_report_iteminfo(FakeItem())
|
||||
|
||||
res = pytest_report_iteminfo(FakeItem())
|
||||
assert res == "-reportinfo-"
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import py
|
||||
|
||||
class DoctestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("doctest options")
|
||||
group.addoption("--doctest-modules",
|
||||
action="store_true", default=False,
|
||||
dest="doctestmodules")
|
||||
|
||||
def pytest_collect_file(self, path, parent):
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.ext == ".py":
|
||||
if parent.config.getvalue("doctestmodules"):
|
||||
return DoctestModule(path, parent)
|
||||
|
@ -76,8 +75,8 @@ class DoctestModule(DoctestItem):
|
|||
#
|
||||
|
||||
class TestDoctests:
|
||||
|
||||
def test_collect_testtextfile(self, testdir):
|
||||
testdir.plugins.append(DoctestPlugin())
|
||||
testdir.maketxtfile(whatever="")
|
||||
checkfile = testdir.maketxtfile(test_something="""
|
||||
alskdjalsdk
|
||||
|
@ -92,7 +91,6 @@ class TestDoctests:
|
|||
assert isinstance(items[0], DoctestTextfile)
|
||||
|
||||
def test_collect_module(self, testdir):
|
||||
testdir.plugins.append(DoctestPlugin())
|
||||
path = testdir.makepyfile(whatever="#")
|
||||
for p in (path, testdir.tmpdir):
|
||||
items, evrec = testdir.inline_genitems(p, '--doctest-modules')
|
||||
|
@ -100,7 +98,6 @@ class TestDoctests:
|
|||
assert isinstance(items[0], DoctestModule)
|
||||
|
||||
def test_simple_doctestfile(self, testdir):
|
||||
testdir.plugins.append(DoctestPlugin())
|
||||
p = testdir.maketxtfile(test_doc="""
|
||||
>>> x = 1
|
||||
>>> x == 1
|
||||
|
@ -112,7 +109,6 @@ class TestDoctests:
|
|||
def test_doctest_unexpected_exception(self, testdir):
|
||||
from py.__.test.outcome import Failed
|
||||
|
||||
testdir.plugins.append(DoctestPlugin())
|
||||
p = testdir.maketxtfile("""
|
||||
>>> i = 0
|
||||
>>> i = 1
|
||||
|
@ -130,7 +126,6 @@ class TestDoctests:
|
|||
#assert repr.reprlocation
|
||||
|
||||
def test_doctestmodule(self, testdir):
|
||||
testdir.plugins.append(DoctestPlugin())
|
||||
p = testdir.makepyfile("""
|
||||
'''
|
||||
>>> x = 1
|
||||
|
@ -143,7 +138,7 @@ class TestDoctests:
|
|||
sorter.assertoutcome(failed=1)
|
||||
|
||||
def test_txtfile_failing(self, testdir):
|
||||
testdir.plugins.append('pytest_doctest')
|
||||
testdir.plugins.append("doctest")
|
||||
p = testdir.maketxtfile("""
|
||||
>>> i = 0
|
||||
>>> i + 1
|
||||
|
@ -162,5 +157,5 @@ class TestDoctests:
|
|||
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(DoctestPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import py
|
||||
|
||||
""" expected to fail.
|
||||
"""
|
||||
|
||||
class EventlogPlugin:
|
||||
""" log pytest events to a file. """
|
||||
def pytest_addoption(self, parser):
|
||||
|
@ -28,7 +31,7 @@ class EventlogPlugin:
|
|||
|
||||
@py.test.mark.xfail
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(EventlogPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
testdir = plugintester.testdir()
|
||||
testdir.makepyfile("""
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import py
|
||||
|
||||
class ExecnetcleanupPlugin:
|
||||
_gateways = None
|
||||
_debug = None
|
||||
def pytest_configure(config):
|
||||
debug = config.option.debug
|
||||
config.pluginmanager.register(Execnetcleanup(debug))
|
||||
|
||||
def pytest_configure(self, config):
|
||||
self._debug = config.option.debug
|
||||
class Execnetcleanup:
|
||||
_gateways = None
|
||||
def __init__(self, debug=False):
|
||||
self._debug = debug
|
||||
|
||||
def trace(self, msg, *args):
|
||||
if self._debug:
|
||||
|
@ -43,7 +45,8 @@ class ExecnetcleanupPlugin:
|
|||
return res
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(ExecnetcleanupPlugin)
|
||||
plugintester.hookcheck(cls=Execnetcleanup)
|
||||
plugintester.hookcheck()
|
||||
|
||||
@py.test.mark.xfail("clarify plugin registration/unregistration")
|
||||
def test_execnetplugin(testdir):
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import py
|
||||
|
||||
class FigleafPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
figleaf = py.test.importorskip("figleaf")
|
||||
import figleaf.annotate_html
|
||||
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup('figleaf options')
|
||||
group.addoption('-F', action='store_true', default=False,
|
||||
dest = 'figleaf',
|
||||
|
@ -14,40 +16,31 @@ class FigleafPlugin:
|
|||
dest='figleafhtml',
|
||||
help='path to the coverage html dir.')
|
||||
|
||||
def pytest_configure(self, config):
|
||||
if config.getvalue('figleaf'):
|
||||
try:
|
||||
import figleaf
|
||||
import figleaf.annotate_html
|
||||
except ImportError:
|
||||
raise config.Error('Could not import figleaf module')
|
||||
self.figleaf = figleaf
|
||||
self.figleaf.start()
|
||||
def pytest_configure(config):
|
||||
figleaf.start()
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
if hasattr(self, 'figleaf'):
|
||||
def pytest_terminal_summary(terminalreporter):
|
||||
config = terminalreporter.config
|
||||
datafile = py.path.local(config.getvalue('figleafdata'))
|
||||
tw = terminalreporter._tw
|
||||
tw.sep('-', 'figleaf')
|
||||
tw.line('Writing figleaf data to %s' % (datafile))
|
||||
self.figleaf.stop()
|
||||
self.figleaf.write_coverage(str(datafile))
|
||||
coverage = self.get_coverage(datafile, config)
|
||||
|
||||
figleaf.stop()
|
||||
figleaf.write_coverage(str(datafile))
|
||||
coverage = get_coverage(datafile, config)
|
||||
reportdir = py.path.local(config.getvalue('figleafhtml'))
|
||||
tw.line('Writing figleaf html to file://%s' % (reportdir))
|
||||
self.figleaf.annotate_html.prepare_reportdir(str(reportdir))
|
||||
figleaf.annotate_html.prepare_reportdir(str(reportdir))
|
||||
exclude = []
|
||||
self.figleaf.annotate_html.report_as_html(coverage,
|
||||
figleaf.annotate_html.report_as_html(coverage,
|
||||
str(reportdir), exclude, {})
|
||||
|
||||
def get_coverage(self, datafile, config):
|
||||
def get_coverage(datafile, config):
|
||||
# basepath = config.topdir
|
||||
basepath = py.path.local()
|
||||
data = self.figleaf.read_coverage(str(datafile))
|
||||
data = figleaf.read_coverage(str(datafile))
|
||||
d = {}
|
||||
coverage = self.figleaf.combine_coverage(d, data)
|
||||
coverage = figleaf.combine_coverage(d, data)
|
||||
for path in coverage.keys():
|
||||
if not py.path.local(path).relto(basepath):
|
||||
del coverage[path]
|
||||
|
@ -55,11 +48,11 @@ class FigleafPlugin:
|
|||
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(FigleafPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_functional(testdir):
|
||||
py.test.importorskip("figleaf")
|
||||
testdir.plugins.append('figleaf')
|
||||
testdir.plugins.append("figleaf")
|
||||
testdir.makepyfile("""
|
||||
def f():
|
||||
x = 42
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import py
|
||||
|
||||
class IocapturePlugin:
|
||||
""" capture sys.stdout/sys.stderr / fd1/fd2. """
|
||||
def pytest_funcarg__stdcapture(self, request):
|
||||
def pytest_funcarg__stdcapture(request):
|
||||
""" capture writes to sys.stdout/sys.stderr. """
|
||||
capture = Capture(py.io.StdCapture)
|
||||
request.addfinalizer(capture.finalize)
|
||||
return capture
|
||||
|
||||
def pytest_funcarg__stdcapturefd(self, request):
|
||||
def pytest_funcarg__stdcapturefd(request):
|
||||
""" capture writes to filedescriptors 1 and 2"""
|
||||
capture = Capture(py.io.StdCaptureFD)
|
||||
request.addfinalizer(capture.finalize)
|
||||
return capture
|
||||
|
@ -26,11 +26,10 @@ class Capture:
|
|||
return res
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(IocapturePlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
class TestCapture:
|
||||
def test_std_functional(self, testdir):
|
||||
testdir.plugins.append(IocapturePlugin())
|
||||
evrec = testdir.inline_runsource("""
|
||||
def test_hello(stdcapture):
|
||||
print 42
|
||||
|
@ -40,7 +39,6 @@ class TestCapture:
|
|||
evrec.assertoutcome(passed=1)
|
||||
|
||||
def test_stdfd_functional(self, testdir):
|
||||
testdir.plugins.append(IocapturePlugin())
|
||||
evrec = testdir.inline_runsource("""
|
||||
def test_hello(stdcapturefd):
|
||||
import os
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import os
|
||||
|
||||
class MonkeypatchPlugin:
|
||||
""" setattr-monkeypatching with automatical reversal after test. """
|
||||
def pytest_funcarg__monkeypatch(self, request):
|
||||
def pytest_funcarg__monkeypatch(request):
|
||||
monkeypatch = MonkeyPatch()
|
||||
request.addfinalizer(monkeypatch.finalize)
|
||||
return monkeypatch
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from py.__.test.custompdb import post_mortem
|
||||
|
||||
class PdbPlugin:
|
||||
def pytest_item_runtest_finished(self, item, excinfo, outerr):
|
||||
def pytest_item_runtest_finished(item, excinfo, outerr):
|
||||
if excinfo and item.config.option.usepdb:
|
||||
tw = py.io.TerminalWriter()
|
||||
repr = excinfo.getrepr()
|
||||
|
|
|
@ -4,32 +4,39 @@ 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):
|
||||
def pytest_funcarg__plugintester(request):
|
||||
return PluginTester(request)
|
||||
|
||||
class PluginTester:
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
|
||||
def testdir(self):
|
||||
def testdir(self, globs=None):
|
||||
from pytest_pytester import TmpTestdir
|
||||
crunner = TmpTestdir(self.request)
|
||||
self.request.addfinalizer(crunner.finalize)
|
||||
testdir = TmpTestdir(self.request)
|
||||
self.request.addfinalizer(testdir.finalize)
|
||||
if globs is None:
|
||||
globs = py.std.sys._getframe(-1).f_globals
|
||||
testdir.plugins.append(globs)
|
||||
#
|
||||
#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
|
||||
return testdir
|
||||
|
||||
def hookcheck(self, pluginclass):
|
||||
print "loading and checking", pluginclass
|
||||
def hookcheck(self, name=None, cls=None):
|
||||
if cls is None:
|
||||
if name is None:
|
||||
name = py.std.sys._getframe(-1).f_globals['__name__']
|
||||
plugin = __import__(name)
|
||||
else:
|
||||
plugin = cls
|
||||
print "checking", plugin
|
||||
fail = False
|
||||
pm = py.test._PluginManager()
|
||||
methods = collectattr(pluginclass)
|
||||
methods = collectattr(plugin)
|
||||
hooks = collectattr(api.PluginHooks)
|
||||
getargs = py.std.inspect.getargs
|
||||
|
||||
|
@ -84,4 +91,4 @@ def formatdef(func):
|
|||
# ===============================================================================
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(PlugintesterPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
|
|
@ -8,19 +8,16 @@ class url:
|
|||
xmlrpc = base + "/xmlrpc/"
|
||||
show = base + "/show/"
|
||||
|
||||
class PocooPlugin:
|
||||
""" report URLs from sending test failures to the pocoo paste service. """
|
||||
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("pocoo plugin")
|
||||
group.addoption('-P', '--pocoo-sendfailures',
|
||||
action='store_true', dest="pocoo_sendfailures",
|
||||
help="send failures to %s paste service" %(url.base,))
|
||||
|
||||
def getproxy(self):
|
||||
def getproxy():
|
||||
return py.std.xmlrpclib.ServerProxy(url.xmlrpc).pastes
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
def pytest_terminal_summary(terminalreporter):
|
||||
if terminalreporter.config.option.pocoo_sendfailures:
|
||||
tr = terminalreporter
|
||||
if 'failed' in tr.stats and tr.config.option.tbstyle != "no":
|
||||
|
@ -28,7 +25,7 @@ class PocooPlugin:
|
|||
terminalreporter.write_line("xmlrpcurl: %s" %(url.xmlrpc,))
|
||||
#print self.__class__.getproxy
|
||||
#print self.__class__, id(self.__class__)
|
||||
serverproxy = self.getproxy()
|
||||
serverproxy = getproxy()
|
||||
for ev in terminalreporter.stats.get('failed'):
|
||||
tw = py.io.TerminalWriter(stringio=True)
|
||||
ev.toterminal(tw)
|
||||
|
@ -42,16 +39,15 @@ class PocooPlugin:
|
|||
|
||||
|
||||
def test_apicheck(plugintester):
|
||||
plugintester.hookcheck(PocooPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_toproxy(testdir, monkeypatch):
|
||||
l = []
|
||||
class MockProxy:
|
||||
def newPaste(self, language, code):
|
||||
l.append((language, code))
|
||||
monkeypatch.setattr(PocooPlugin, 'getproxy', MockProxy)
|
||||
testdir.plugins.insert(0, PocooPlugin())
|
||||
testdir.chdir()
|
||||
monkeypatch.setitem(globals(), 'getproxy', MockProxy)
|
||||
testdir.plugins.insert(0, globals())
|
||||
testpath = testdir.makepyfile("""
|
||||
import py
|
||||
def test_pass():
|
||||
|
|
|
@ -5,33 +5,22 @@ XXX: Currently in progress, NOT IN WORKING STATE.
|
|||
"""
|
||||
import py
|
||||
|
||||
class PylintPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
lint = py.test.importorskip("pylint")
|
||||
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup('pylint options')
|
||||
group.addoption('--pylint', action='store_true',
|
||||
default=False, dest='pylint',
|
||||
help='Pylint coverate of test files.')
|
||||
|
||||
def pytest_configure(self, config):
|
||||
if config.getvalue('pylint'):
|
||||
try:
|
||||
from pylint import lint
|
||||
self.lint = lint
|
||||
except ImportError:
|
||||
raise config.Error('Could not import pylint module')
|
||||
print "trying to configure pytest"
|
||||
|
||||
def pytest_collect_file(self, path, parent):
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.ext == ".py":
|
||||
if parent.config.getvalue('pylint'):
|
||||
return PylintItem(path, parent, self.lint)
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
if hasattr(self, 'lint'):
|
||||
def pytest_terminal_summary(terminalreporter):
|
||||
print 'placeholder for pylint output'
|
||||
|
||||
|
||||
|
||||
class PylintItem(py.test.collect.Item):
|
||||
def __init__(self, path, parent, lintlib):
|
||||
name = self.__class__.__name__ + ":" + path.basename
|
||||
|
|
|
@ -10,25 +10,23 @@ from py.__.test.config import Config as pytestConfig
|
|||
from pytest__pytest import CallRecorder
|
||||
import api
|
||||
|
||||
|
||||
class PytesterPlugin:
|
||||
def pytest_funcarg__linecomp(self, request):
|
||||
def pytest_funcarg__linecomp(request):
|
||||
return LineComp()
|
||||
|
||||
def pytest_funcarg__LineMatcher(self, request):
|
||||
def pytest_funcarg__LineMatcher(request):
|
||||
return LineMatcher
|
||||
|
||||
def pytest_funcarg__testdir(self, request):
|
||||
def pytest_funcarg__testdir(request):
|
||||
tmptestdir = TmpTestdir(request)
|
||||
return tmptestdir
|
||||
|
||||
def pytest_funcarg__eventrecorder(self, request):
|
||||
def pytest_funcarg__eventrecorder(request):
|
||||
evrec = EventRecorder(py._com.comregistry)
|
||||
request.addfinalizer(lambda: evrec.comregistry.unregister(evrec))
|
||||
return evrec
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(PytesterPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
class RunResult:
|
||||
def __init__(self, ret, outlines, errlines):
|
||||
|
@ -163,7 +161,9 @@ class TmpTestdir:
|
|||
for plugin in self.plugins:
|
||||
if isinstance(plugin, str):
|
||||
config.pluginmanager.import_plugin(plugin)
|
||||
else:
|
||||
elif plugin:
|
||||
if isinstance(plugin, dict):
|
||||
plugin = PseudoPlugin(plugin)
|
||||
config.pluginmanager.register(plugin)
|
||||
return config
|
||||
|
||||
|
@ -280,6 +280,11 @@ class TmpTestdir:
|
|||
child.timeout = expect_timeout
|
||||
return child
|
||||
|
||||
class PseudoPlugin:
|
||||
def __init__(self, vars):
|
||||
self.__dict__.update(vars)
|
||||
|
||||
|
||||
class Event:
|
||||
def __init__(self, name, args, kwargs):
|
||||
self.name = name
|
||||
|
|
|
@ -7,8 +7,7 @@ to a user. See the test at the bottom for an example.
|
|||
import py
|
||||
import os
|
||||
|
||||
class RecwarnPlugin:
|
||||
def pytest_funcarg__recwarn(self, request):
|
||||
def pytest_funcarg__recwarn(request):
|
||||
""" check that warnings have been raised. """
|
||||
warnings = WarningsRecorder()
|
||||
request.addfinalizer(warnings.finalize)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import py
|
||||
|
||||
class RestdocPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("ReST", "ReST documentation check options")
|
||||
group.addoption('-R', '--urlcheck',
|
||||
action="store_true", dest="urlcheck", default=False,
|
||||
|
@ -13,7 +12,7 @@ class RestdocPlugin:
|
|||
action="store_true", dest="forcegen", default=False,
|
||||
help="force generation of html files.")
|
||||
|
||||
def pytest_collect_file(self, path, parent):
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.ext == ".txt":
|
||||
project = getproject(path)
|
||||
if project is not None:
|
||||
|
@ -346,7 +345,7 @@ def localrefcheck(tryfn, path, lineno):
|
|||
# PLUGIN tests
|
||||
#
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(RestdocPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_deindent():
|
||||
assert deindent('foo') == 'foo'
|
||||
|
@ -388,18 +387,18 @@ class TestApigenLinkRole:
|
|||
"resolve_linkrole('source', 'py/foo/bar.py')")
|
||||
|
||||
|
||||
def pytest_funcarg__testdir(request):
|
||||
class TestDoctest:
|
||||
def pytest_funcarg__testdir(self, request):
|
||||
testdir = request.call_next_provider()
|
||||
assert request.module.__name__ == __name__
|
||||
testdir.makepyfile(confrest="from py.__.misc.rest import Project")
|
||||
testdir.plugins.append(RestdocPlugin())
|
||||
count = 0
|
||||
for p in testdir.plugins:
|
||||
if isinstance(p, RestdocPlugin):
|
||||
count += 1
|
||||
assert count < 2
|
||||
if p == globals():
|
||||
break
|
||||
else:
|
||||
testdir.plugins.append(globals())
|
||||
return testdir
|
||||
|
||||
class TestDoctest:
|
||||
def test_doctest_extra_exec(self, testdir):
|
||||
xtxt = testdir.maketxtfile(x="""
|
||||
hello::
|
||||
|
|
|
@ -365,7 +365,7 @@ class TestWithFunctionIntegration:
|
|||
assert 'ValueError' in entry
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(ResultdbPlugin)
|
||||
plugintester.hookcheck()
|
||||
testdir = plugintester.testdir()
|
||||
testdir.makepyfile("""
|
||||
import py
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
import py
|
||||
|
||||
class ResultlogPlugin:
|
||||
"""resultlog plugin for machine-readable logging of test results.
|
||||
Useful for buildbot integration code.
|
||||
"""
|
||||
def pytest_addoption(self, parser):
|
||||
|
||||
import py
|
||||
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("resultlog", "resultlog plugin options")
|
||||
group.addoption('--resultlog', action="store", dest="resultlog", metavar="path",
|
||||
help="path for machine-readable result log.")
|
||||
|
||||
def pytest_configure(self, config):
|
||||
def pytest_configure(config):
|
||||
resultlog = config.option.resultlog
|
||||
if resultlog:
|
||||
logfile = open(resultlog, 'w', 1) # line buffered
|
||||
self.resultlog = ResultLog(logfile)
|
||||
config.pluginmanager.register(self.resultlog)
|
||||
config._resultlog = ResultLog(logfile)
|
||||
config.pluginmanager.register(config._resultlog)
|
||||
|
||||
def pytest_unconfigure(self, config):
|
||||
if hasattr(self, 'resultlog'):
|
||||
self.resultlog.logfile.close()
|
||||
del self.resultlog
|
||||
#config.pluginmanager.unregister(self.resultlog)
|
||||
def pytest_unconfigure(config):
|
||||
resultlog = getattr(config, '_resultlog', None)
|
||||
if resultlog:
|
||||
resultlog.logfile.close()
|
||||
del config.resultlog
|
||||
config.pluginmanager.unregister(resultlog)
|
||||
|
||||
def generic_path(item):
|
||||
chain = item.listchain()
|
||||
|
@ -224,7 +225,7 @@ class TestWithFunctionIntegration:
|
|||
assert 'ValueError' in entry
|
||||
|
||||
def test_generic(plugintester, LineMatcher):
|
||||
plugintester.hookcheck(ResultlogPlugin)
|
||||
plugintester.hookcheck()
|
||||
testdir = plugintester.testdir()
|
||||
testdir.plugins.append("resultlog")
|
||||
testdir.makepyfile("""
|
||||
|
|
|
@ -146,7 +146,7 @@ class SetupState(object):
|
|||
# ===============================================================================
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(RunnerPlugin())
|
||||
plugintester.hookcheck()
|
||||
|
||||
class TestSetupState:
|
||||
def test_setup_prepare(self, testdir):
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
import py
|
||||
import sys
|
||||
|
||||
class TerminalPlugin(object):
|
||||
""" Report a test run to a terminal. """
|
||||
def pytest_configure(self, config):
|
||||
def pytest_configure(config):
|
||||
if config.option.collectonly:
|
||||
self.reporter = CollectonlyReporter(config)
|
||||
reporter = CollectonlyReporter(config)
|
||||
else:
|
||||
self.reporter = TerminalReporter(config)
|
||||
reporter = TerminalReporter(config)
|
||||
# XXX see remote.py's XXX
|
||||
for attr in 'pytest_terminal_hasmarkup', 'pytest_terminal_fullwidth':
|
||||
if hasattr(config, attr):
|
||||
#print "SETTING TERMINAL OPTIONS", attr, getattr(config, attr)
|
||||
name = attr.split("_")[-1]
|
||||
assert hasattr(self.reporter._tw, name), name
|
||||
setattr(self.reporter._tw, name, getattr(config, attr))
|
||||
config.pluginmanager.register(self.reporter)
|
||||
setattr(reporter._tw, name, getattr(config, attr))
|
||||
config.pluginmanager.register(reporter)
|
||||
|
||||
class TerminalReporter:
|
||||
def __init__(self, config, file=None):
|
||||
|
@ -143,7 +141,6 @@ class TerminalReporter:
|
|||
def pytest_deselected(self, items):
|
||||
self.stats.setdefault('deselected', []).append(items)
|
||||
|
||||
|
||||
def pytest_itemstart(self, item, node=None):
|
||||
if self.config.option.dist != "no":
|
||||
# for dist-testing situations itemstart means we
|
||||
|
@ -749,6 +746,6 @@ def test_repr_python_version(monkeypatch):
|
|||
assert repr_pythonversion() == str(x)
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(TerminalPlugin)
|
||||
plugintester.hookcheck(TerminalReporter)
|
||||
plugintester.hookcheck(CollectonlyReporter)
|
||||
plugintester.hookcheck()
|
||||
plugintester.hookcheck(cls=TerminalReporter)
|
||||
plugintester.hookcheck(cls=CollectonlyReporter)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""
|
||||
provide temporary directories to test functions and methods.
|
||||
|
||||
example:
|
||||
|
||||
pytest_plugins = "pytest_tmpdir"
|
||||
|
@ -9,11 +11,7 @@ example:
|
|||
"""
|
||||
import py
|
||||
|
||||
class TmpdirPlugin:
|
||||
""" provide temporary directories to test functions and methods.
|
||||
"""
|
||||
|
||||
def pytest_funcarg__tmpdir(self, request):
|
||||
def pytest_funcarg__tmpdir(request):
|
||||
name = request.function.__name__
|
||||
return request.config.mktemp(name, numbered=True)
|
||||
|
||||
|
@ -24,13 +22,12 @@ class TmpdirPlugin:
|
|||
# ===============================================================================
|
||||
#
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(TmpdirPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_funcarg(testdir):
|
||||
from py.__.test.funcargs import FuncargRequest
|
||||
item = testdir.getitem("def test_func(tmpdir): pass")
|
||||
plugin = TmpdirPlugin()
|
||||
p = plugin.pytest_funcarg__tmpdir(FuncargRequest(item, "tmpdir"))
|
||||
p = pytest_funcarg__tmpdir(FuncargRequest(item, "tmpdir"))
|
||||
assert p.check()
|
||||
bn = p.basename.strip("0123456789-")
|
||||
assert bn.endswith("test_func")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
automatically collect and run traditional "unittest.py" style tests.
|
||||
automatically discover and run traditional "unittest.py" style tests.
|
||||
|
||||
you can mix unittest TestCase subclasses and
|
||||
py.test style tests in one test module.
|
||||
|
@ -15,10 +15,7 @@ $Id: conftest.py 60979 2009-01-14 22:29:32Z hpk $
|
|||
"""
|
||||
import py
|
||||
|
||||
class UnittestPlugin:
|
||||
""" discover and integrate traditional ``unittest.py`` tests.
|
||||
"""
|
||||
def pytest_pycollect_obj(self, collector, name, obj):
|
||||
def pytest_pycollect_obj(collector, name, obj):
|
||||
if py.std.inspect.isclass(obj) and issubclass(obj, py.std.unittest.TestCase):
|
||||
return UnitTestCase(name, parent=collector)
|
||||
|
||||
|
@ -71,7 +68,7 @@ class UnitTestFunction(py.test.collect.Function):
|
|||
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(UnittestPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_simple_unittest(testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""
|
||||
mark and report specially about "expected to fail" tests.
|
||||
|
||||
for marking and reporting "expected to fail" tests.
|
||||
@py.test.mark.xfail("needs refactoring")
|
||||
def test_hello():
|
||||
|
@ -7,10 +9,7 @@ for marking and reporting "expected to fail" tests.
|
|||
"""
|
||||
import py
|
||||
|
||||
class XfailPlugin(object):
|
||||
""" mark and report specially about "expected to fail" tests. """
|
||||
|
||||
def pytest_item_makereport(self, __call__, item, excinfo, when, outerr):
|
||||
def pytest_item_makereport(__call__, item, excinfo, when, outerr):
|
||||
if hasattr(item, 'obj') and hasattr(item.obj, 'func_dict'):
|
||||
if 'xfail' in item.obj.func_dict:
|
||||
res = __call__.execute(firstresult=True)
|
||||
|
@ -22,7 +21,7 @@ class XfailPlugin(object):
|
|||
res.failed = True
|
||||
return res
|
||||
|
||||
def pytest_report_teststatus(self, rep):
|
||||
def pytest_report_teststatus(rep):
|
||||
""" return shortletter and verbose word. """
|
||||
if 'xfail' in rep.keywords:
|
||||
if rep.skipped:
|
||||
|
@ -31,7 +30,7 @@ class XfailPlugin(object):
|
|||
return "xpassed", "P", "xpass"
|
||||
|
||||
# a hook implemented called by the terminalreporter instance/plugin
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
def pytest_terminal_summary(terminalreporter):
|
||||
tr = terminalreporter
|
||||
xfailed = tr.stats.get("xfailed")
|
||||
if xfailed:
|
||||
|
@ -57,7 +56,7 @@ class XfailPlugin(object):
|
|||
# ===============================================================================
|
||||
|
||||
def test_generic(plugintester):
|
||||
plugintester.hookcheck(XfailPlugin)
|
||||
plugintester.hookcheck()
|
||||
|
||||
def test_xfail(plugintester, linecomp):
|
||||
testdir = plugintester.testdir()
|
||||
|
|
|
@ -4,6 +4,10 @@ managing loading and interacting with pytest plugins.
|
|||
import py
|
||||
from py.__.test.plugin import api
|
||||
|
||||
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, comregistry=None):
|
||||
if comregistry is None:
|
||||
|
@ -16,14 +20,21 @@ class PluginManager(object):
|
|||
hookspecs=api.PluginHooks,
|
||||
registry=self.comregistry)
|
||||
|
||||
def register(self, plugin):
|
||||
def register(self, plugin, name=None):
|
||||
if name is None:
|
||||
name = getattr(plugin, '__name__', id(plugin))
|
||||
if name not in self.impname2plugin:
|
||||
self.impname2plugin[name] = plugin
|
||||
self.hook.pytest_plugin_registered(plugin=plugin)
|
||||
import types
|
||||
self.comregistry.register(plugin)
|
||||
return True
|
||||
|
||||
def unregister(self, plugin):
|
||||
self.hook.pytest_plugin_unregistered(plugin=plugin)
|
||||
self.comregistry.unregister(plugin)
|
||||
for name, value in self.impname2plugin.items():
|
||||
if value == plugin:
|
||||
del self.impname2plugin[name]
|
||||
|
||||
def isregistered(self, plugin):
|
||||
return self.comregistry.isregistered(plugin)
|
||||
|
@ -34,7 +45,7 @@ class PluginManager(object):
|
|||
# API for bootstrapping
|
||||
#
|
||||
def getplugin(self, importname):
|
||||
impname, clsname = canonical_names(importname)
|
||||
impname = canonical_importname(importname)
|
||||
return self.impname2plugin[impname]
|
||||
|
||||
def _envlist(self, varname):
|
||||
|
@ -54,9 +65,10 @@ class PluginManager(object):
|
|||
|
||||
def consider_conftest(self, conftestmodule):
|
||||
cls = getattr(conftestmodule, 'ConftestPlugin', None)
|
||||
if cls is not None and cls not in self.impname2plugin:
|
||||
self.impname2plugin[cls] = True
|
||||
self.register(cls())
|
||||
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):
|
||||
|
@ -69,12 +81,12 @@ class PluginManager(object):
|
|||
|
||||
def import_plugin(self, spec):
|
||||
assert isinstance(spec, str)
|
||||
modname, clsname = canonical_names(spec)
|
||||
modname = canonical_importname(spec)
|
||||
if modname in self.impname2plugin:
|
||||
return
|
||||
mod = importplugin(modname)
|
||||
plugin = registerplugin(self.register, mod, clsname)
|
||||
self.impname2plugin[modname] = plugin
|
||||
check_old_use(mod, modname)
|
||||
self.register(mod)
|
||||
self.consider_module(mod)
|
||||
#
|
||||
#
|
||||
|
@ -131,19 +143,12 @@ class PluginManager(object):
|
|||
#
|
||||
# XXX old code to automatically load classes
|
||||
#
|
||||
def canonical_names(importspec):
|
||||
importspec = importspec.lower()
|
||||
def canonical_importname(name):
|
||||
name = name.lower()
|
||||
modprefix = "pytest_"
|
||||
if not importspec.startswith(modprefix):
|
||||
importspec = modprefix + importspec
|
||||
clsname = importspec[len(modprefix):].capitalize() + "Plugin"
|
||||
return importspec, clsname
|
||||
|
||||
def registerplugin(registerfunc, mod, clsname):
|
||||
pluginclass = getattr(mod, clsname)
|
||||
plugin = pluginclass()
|
||||
registerfunc(plugin)
|
||||
return plugin
|
||||
if not name.startswith(modprefix):
|
||||
name = modprefix + name
|
||||
return name
|
||||
|
||||
def importplugin(importspec):
|
||||
try:
|
||||
|
|
|
@ -5,8 +5,7 @@ EXPECTTIMEOUT=10.0
|
|||
class TestGeneralUsage:
|
||||
def test_config_error(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_configure(self, config):
|
||||
def pytest_configure(config):
|
||||
raise config.Error("hello")
|
||||
""")
|
||||
result = testdir.runpytest(testdir.tmpdir)
|
||||
|
@ -17,8 +16,7 @@ class TestGeneralUsage:
|
|||
|
||||
def test_config_preparse_plugin_option(self, testdir):
|
||||
testdir.makepyfile(pytest_xyz="""
|
||||
class XyzPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--xyz", dest="xyz", action="store")
|
||||
""")
|
||||
testdir.makepyfile(test_one="""
|
||||
|
|
|
@ -193,10 +193,9 @@ class TestCustomConftests:
|
|||
|
||||
def test_avoid_directory_on_option(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--XX", action="store_true", default=False)
|
||||
def pytest_collect_recurse(self, path, parent):
|
||||
def pytest_collect_recurse(path, parent):
|
||||
return parent.config.getvalue("XX")
|
||||
""")
|
||||
testdir.mkdir("hello")
|
||||
|
|
|
@ -19,8 +19,7 @@ def test_getfuncargnames():
|
|||
class TestFillFuncArgs:
|
||||
def test_funcarg_lookupfails(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_funcarg__xyzsomething(self, request):
|
||||
def pytest_funcarg__xyzsomething(request):
|
||||
return 42
|
||||
""")
|
||||
item = testdir.getitem("def test_func(some): pass")
|
||||
|
@ -67,6 +66,19 @@ class TestFillFuncArgs:
|
|||
funcargs.fillfuncargs(item2)
|
||||
assert item2.funcargs['something'] == "test_func"
|
||||
|
||||
def test_funcarg_lookup_classlevel(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
class TestClass:
|
||||
def pytest_funcarg__something(self, request):
|
||||
return request.instance
|
||||
def test_method(self, something):
|
||||
assert something is self
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*1 passed*"
|
||||
])
|
||||
|
||||
class TestRequest:
|
||||
def test_request_attributes(self, testdir):
|
||||
item = testdir.getitem("""
|
||||
|
@ -90,6 +102,7 @@ class TestRequest:
|
|||
""")
|
||||
req = funcargs.FuncargRequest(item, argname="something")
|
||||
assert req.cls.__name__ == "TestB"
|
||||
assert req.instance.__class__ == req.cls
|
||||
|
||||
def test_request_contains_funcargs_provider(self, testdir):
|
||||
modcol = testdir.getmodulecol("""
|
||||
|
@ -284,8 +297,7 @@ class TestGenfuncFunctional:
|
|||
|
||||
def test_addcall_with_funcargs_two(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_generate_tests(self, metafunc):
|
||||
def pytest_generate_tests(metafunc):
|
||||
assert "arg1" in metafunc.funcargnames
|
||||
metafunc.addcall(funcargs=dict(arg1=1, arg2=2))
|
||||
""")
|
||||
|
@ -328,8 +340,7 @@ class TestGenfuncFunctional:
|
|||
|
||||
def test_generate_plugin_and_module(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_generate_tests(self, metafunc):
|
||||
def pytest_generate_tests(metafunc):
|
||||
assert "arg1" in metafunc.funcargnames
|
||||
metafunc.addcall(id="world", param=(2,100))
|
||||
""")
|
||||
|
|
|
@ -87,8 +87,7 @@ class TestConfigPickling:
|
|||
|
||||
def test_config_pickling_customoption(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("testing group")
|
||||
group.addoption('-G', '--glong', action="store", default=42,
|
||||
type="int", dest="gdest", help="g value.")
|
||||
|
@ -108,8 +107,7 @@ class TestConfigPickling:
|
|||
tmp = testdir.tmpdir.ensure("w1", "w2", dir=1)
|
||||
tmp.ensure("__init__.py")
|
||||
tmp.join("conftest.py").write(py.code.Source("""
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
group = parser.addgroup("testing group")
|
||||
group.addoption('-G', '--glong', action="store", default=42,
|
||||
type="int", dest="gdest", help="g value.")
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import py, os
|
||||
from py.__.test.pluginmanager import PluginManager, canonical_names
|
||||
from py.__.test.pluginmanager import registerplugin, importplugin
|
||||
from py.__.test.pluginmanager import PluginManager, canonical_importname
|
||||
|
||||
class TestBootstrapping:
|
||||
def test_consider_env_fails_to_import(self, monkeypatch):
|
||||
|
@ -17,7 +16,7 @@ class TestBootstrapping:
|
|||
def test_consider_env_plugin_instantiation(self, testdir, monkeypatch):
|
||||
pluginmanager = PluginManager()
|
||||
testdir.syspathinsert()
|
||||
testdir.makepyfile(pytest_xy123="class Xy123Plugin: pass")
|
||||
testdir.makepyfile(pytest_xy123="#")
|
||||
monkeypatch.setitem(os.environ, 'PYTEST_PLUGINS', 'xy123')
|
||||
l1 = len(pluginmanager.getplugins())
|
||||
pluginmanager.consider_env()
|
||||
|
@ -29,7 +28,7 @@ class TestBootstrapping:
|
|||
assert l2 == l3
|
||||
|
||||
def test_pluginmanager_ENV_startup(self, testdir, monkeypatch):
|
||||
x500 = testdir.makepyfile(pytest_x500="class X500Plugin: pass")
|
||||
x500 = testdir.makepyfile(pytest_x500="#")
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
def test_hello():
|
||||
|
@ -48,59 +47,49 @@ class TestBootstrapping:
|
|||
|
||||
reset = testdir.syspathinsert()
|
||||
pluginname = "pytest_hello"
|
||||
testdir.makepyfile(**{pluginname: """
|
||||
class HelloPlugin:
|
||||
pass
|
||||
"""})
|
||||
testdir.makepyfile(**{pluginname: ""})
|
||||
pluginmanager.import_plugin("hello")
|
||||
len1 = len(pluginmanager.getplugins())
|
||||
pluginmanager.import_plugin("pytest_hello")
|
||||
len2 = len(pluginmanager.getplugins())
|
||||
assert len1 == len2
|
||||
plugin1 = pluginmanager.getplugin("pytest_hello")
|
||||
assert plugin1.__class__.__name__ == 'HelloPlugin'
|
||||
assert plugin1.__name__.endswith('pytest_hello')
|
||||
plugin2 = pluginmanager.getplugin("hello")
|
||||
assert plugin2 is plugin1
|
||||
|
||||
def test_consider_module(self, testdir):
|
||||
pluginmanager = PluginManager()
|
||||
testdir.syspathinsert()
|
||||
testdir.makepyfile(pytest_plug1="class Plug1Plugin: pass")
|
||||
testdir.makepyfile(pytest_plug2="class Plug2Plugin: pass")
|
||||
testdir.makepyfile(pytest_plug1="#")
|
||||
testdir.makepyfile(pytest_plug2="#")
|
||||
mod = py.std.new.module("temp")
|
||||
mod.pytest_plugins = ["pytest_plug1", "pytest_plug2"]
|
||||
pluginmanager.consider_module(mod)
|
||||
assert pluginmanager.getplugin("plug1").__class__.__name__ == "Plug1Plugin"
|
||||
assert pluginmanager.getplugin("plug2").__class__.__name__ == "Plug2Plugin"
|
||||
assert pluginmanager.getplugin("plug1").__name__ == "pytest_plug1"
|
||||
assert pluginmanager.getplugin("plug2").__name__ == "pytest_plug2"
|
||||
|
||||
def test_consider_module_import_module(self, testdir):
|
||||
mod = py.std.new.module("x")
|
||||
mod.pytest_plugins = "pytest_a"
|
||||
aplugin = testdir.makepyfile(pytest_a="""class APlugin: pass""")
|
||||
aplugin = testdir.makepyfile(pytest_a="#")
|
||||
pluginmanager = PluginManager()
|
||||
sorter = testdir.geteventrecorder(pluginmanager)
|
||||
#syspath.prepend(aplugin.dirpath())
|
||||
py.std.sys.path.insert(0, str(aplugin.dirpath()))
|
||||
pluginmanager.consider_module(mod)
|
||||
call = sorter.getcall(pluginmanager.hook.pytest_plugin_registered.name)
|
||||
assert call.plugin.__class__.__name__ == "APlugin"
|
||||
assert call.plugin.__name__ == "pytest_a"
|
||||
|
||||
# check that it is not registered twice
|
||||
pluginmanager.consider_module(mod)
|
||||
l = sorter.getcalls("plugin_registered")
|
||||
assert len(l) == 1
|
||||
|
||||
def test_consider_conftest(self, testdir):
|
||||
def test_consider_conftest_deprecated(self, testdir):
|
||||
pp = PluginManager()
|
||||
mod = testdir.makepyfile("class ConftestPlugin: hello = 1").pyimport()
|
||||
pp.consider_conftest(mod)
|
||||
l = [x for x in pp.getplugins() if isinstance(x, mod.ConftestPlugin)]
|
||||
assert len(l) == 1
|
||||
assert l[0].hello == 1
|
||||
|
||||
pp.consider_conftest(mod)
|
||||
l = [x for x in pp.getplugins() if isinstance(x, mod.ConftestPlugin)]
|
||||
assert len(l) == 1
|
||||
mod = testdir.makepyfile("class ConftestPlugin: pass").pyimport()
|
||||
call = py.test.raises(ValueError, pp.consider_conftest, mod)
|
||||
|
||||
def test_config_sets_conftesthandle_onimport(self, testdir):
|
||||
config = testdir.parseconfig([])
|
||||
|
@ -124,32 +113,15 @@ class TestBootstrapping:
|
|||
pp.unregister(a2)
|
||||
assert not pp.isregistered(a2)
|
||||
|
||||
def test_canonical_names(self):
|
||||
def test_canonical_importname(self):
|
||||
for name in 'xyz', 'pytest_xyz', 'pytest_Xyz', 'Xyz':
|
||||
impname, clsname = canonical_names(name)
|
||||
assert impname == "pytest_xyz"
|
||||
assert clsname == "XyzPlugin"
|
||||
|
||||
def test_registerplugin(self):
|
||||
l = []
|
||||
registerfunc = l.append
|
||||
registerplugin(registerfunc, py.io, "TerminalWriter")
|
||||
assert len(l) == 1
|
||||
assert isinstance(l[0], py.io.TerminalWriter)
|
||||
|
||||
def test_importplugin(self):
|
||||
assert importplugin("py") == py
|
||||
py.test.raises(ImportError, "importplugin('laksjd.qwe')")
|
||||
mod = importplugin("pytest_terminal")
|
||||
assert mod is py.__.test.plugin.pytest_terminal
|
||||
|
||||
impname = canonical_importname(name)
|
||||
|
||||
class TestPytestPluginInteractions:
|
||||
def test_do_option_conftestplugin(self, testdir):
|
||||
from py.__.test.config import Config
|
||||
p = testdir.makepyfile("""
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption('--test123', action="store_true")
|
||||
""")
|
||||
config = Config()
|
||||
|
@ -165,8 +137,7 @@ class TestPytestPluginInteractions:
|
|||
config.pluginmanager.do_configure(config=config)
|
||||
assert not hasattr(config.option, 'test123')
|
||||
p = testdir.makepyfile("""
|
||||
class ConftestPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption('--test123', action="store_true",
|
||||
default=True)
|
||||
""")
|
||||
|
|
|
@ -255,6 +255,19 @@ class TestFunction:
|
|||
assert f5 != f5b
|
||||
assert not (f5 == f5b)
|
||||
|
||||
class callspec1:
|
||||
param = 1
|
||||
funcargs = {}
|
||||
class callspec2:
|
||||
param = 2
|
||||
funcargs = {}
|
||||
f5 = py.test.collect.Function(name="name", config=config,
|
||||
callspec=callspec1, callobj=isinstance)
|
||||
f5b = py.test.collect.Function(name="name", config=config,
|
||||
callspec=callspec2, callobj=isinstance)
|
||||
assert f5 != f5b
|
||||
assert not (f5 == f5b)
|
||||
|
||||
class TestSorting:
|
||||
def test_check_equality_and_cmp_basic(self, testdir):
|
||||
modcol = testdir.getmodulecol("""
|
||||
|
|
|
@ -9,8 +9,7 @@ class TestTracebackCutting:
|
|||
|
||||
def test_traceback_argsetup(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
class ConftestPlugin:
|
||||
def pytest_funcarg__hello(self, request):
|
||||
def pytest_funcarg__hello(request):
|
||||
raise ValueError("xyz")
|
||||
""")
|
||||
p = testdir.makepyfile("def test(hello): pass")
|
||||
|
@ -18,12 +17,12 @@ class TestTracebackCutting:
|
|||
assert result.ret != 0
|
||||
out = result.stdout.str()
|
||||
assert out.find("xyz") != -1
|
||||
assert out.find("conftest.py:3: ValueError") != -1
|
||||
assert out.find("conftest.py:2: ValueError") != -1
|
||||
numentries = out.count("_ _ _") # separator for traceback entries
|
||||
assert numentries == 0
|
||||
|
||||
result = testdir.runpytest("--fulltrace", p)
|
||||
out = result.stdout.str()
|
||||
assert out.find("conftest.py:3: ValueError") != -1
|
||||
assert out.find("conftest.py:2: ValueError") != -1
|
||||
numentries = out.count("_ _ _ _") # separator for traceback entries
|
||||
assert numentries >3
|
||||
|
|
Loading…
Reference in New Issue