rename a number of internal and externally visible variables to use the fixture name
rather than funcargs. Introduce .funcargnames compatibility attribute for backward compat.
This commit is contained in:
parent
8282efbb40
commit
bb07ba7807
|
@ -71,7 +71,7 @@ introduction of this new method needs to be _fully_ backward compatible -
|
||||||
and the documentation needs to change along to mention this new way of
|
and the documentation needs to change along to mention this new way of
|
||||||
doing things.
|
doing things.
|
||||||
|
|
||||||
impl note: probably Request._fillfuncargs would be called from the
|
impl note: probably Request._fillfixtures would be called from the
|
||||||
python plugins own pytest_runtest_setup(item) and would call
|
python plugins own pytest_runtest_setup(item) and would call
|
||||||
item.getresource(X) for all X in the funcargs of a function.
|
item.getresource(X) for all X in the funcargs of a function.
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ def pytest_funcarg__capsys(request):
|
||||||
"""
|
"""
|
||||||
if "capfd" in request._funcargs:
|
if "capfd" in request._funcargs:
|
||||||
raise request.raiseerror(error_capsysfderror)
|
raise request.raiseerror(error_capsysfderror)
|
||||||
return CaptureFuncarg(py.io.StdCapture)
|
return CaptureFixture(py.io.StdCapture)
|
||||||
|
|
||||||
def pytest_funcarg__capfd(request):
|
def pytest_funcarg__capfd(request):
|
||||||
"""enables capturing of writes to file descriptors 1 and 2 and makes
|
"""enables capturing of writes to file descriptors 1 and 2 and makes
|
||||||
|
@ -200,9 +200,9 @@ def pytest_funcarg__capfd(request):
|
||||||
request.raiseerror(error_capsysfderror)
|
request.raiseerror(error_capsysfderror)
|
||||||
if not hasattr(os, 'dup'):
|
if not hasattr(os, 'dup'):
|
||||||
pytest.skip("capfd funcarg needs os.dup")
|
pytest.skip("capfd funcarg needs os.dup")
|
||||||
return CaptureFuncarg(py.io.StdCaptureFD)
|
return CaptureFixture(py.io.StdCaptureFD)
|
||||||
|
|
||||||
class CaptureFuncarg:
|
class CaptureFixture:
|
||||||
def __init__(self, captureclass):
|
def __init__(self, captureclass):
|
||||||
self.capture = captureclass(now=False)
|
self.capture = captureclass(now=False)
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ def showhelp(config):
|
||||||
tw.line() ; tw.line()
|
tw.line() ; tw.line()
|
||||||
#tw.sep("=")
|
#tw.sep("=")
|
||||||
tw.line("to see available markers type: py.test --markers")
|
tw.line("to see available markers type: py.test --markers")
|
||||||
tw.line("to see available funcargs type: py.test --funcargs")
|
tw.line("to see available fixtures type: py.test --fixtures")
|
||||||
return
|
return
|
||||||
|
|
||||||
tw.line("conftest.py options:")
|
tw.line("conftest.py options:")
|
||||||
|
|
|
@ -308,8 +308,8 @@ class Node(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _repr_failure_py(self, excinfo, style=None):
|
def _repr_failure_py(self, excinfo, style=None):
|
||||||
fm = self.session.funcargmanager
|
fm = self.session._fixturemanager
|
||||||
if excinfo.errisinstance(fm.FuncargLookupError):
|
if excinfo.errisinstance(fm.FixtureLookupError):
|
||||||
function = excinfo.value.function
|
function = excinfo.value.function
|
||||||
factblines = excinfo.value.factblines
|
factblines = excinfo.value.factblines
|
||||||
if function is not None:
|
if function is not None:
|
||||||
|
@ -317,7 +317,7 @@ class Node(object):
|
||||||
lines, _ = inspect.getsourcelines(function)
|
lines, _ = inspect.getsourcelines(function)
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
if line.strip().startswith('def'):
|
if line.strip().startswith('def'):
|
||||||
return fm.FuncargLookupErrorRepr(fspath,
|
return fm.FixtureLookupErrorRepr(fspath,
|
||||||
lineno, lines[:i+1],
|
lineno, lines[:i+1],
|
||||||
str(excinfo.value.msg), factblines)
|
str(excinfo.value.msg), factblines)
|
||||||
if self.config.option.fulltrace:
|
if self.config.option.fulltrace:
|
||||||
|
|
|
@ -44,18 +44,7 @@ defaultfuncargprefixmarker = fixture()
|
||||||
|
|
||||||
# XXX remove in favour of fixture(autoactive=True)
|
# XXX remove in favour of fixture(autoactive=True)
|
||||||
def setup(scope="function"):
|
def setup(scope="function"):
|
||||||
""" return a decorator to mark a function as providing a fixture for
|
""" alias for fixture(scope, autoactive=True) """
|
||||||
a testcontext. A fixture function is executed for each scope and may
|
|
||||||
receive funcargs which allows it to initialise and provide implicit
|
|
||||||
test state. A fixture function may receive the "testcontext" object
|
|
||||||
and register a finalizer via "testcontext.addfinalizer(finalizer)"
|
|
||||||
which will be called when the last test in the testcontext has
|
|
||||||
executed.
|
|
||||||
|
|
||||||
:arg scope: the scope for which the setup function will be active, one
|
|
||||||
of "function", "class", "module", "session".
|
|
||||||
Defaults to "function".
|
|
||||||
"""
|
|
||||||
return FixtureFunctionMarker(scope, params=None, autoactive=True)
|
return FixtureFunctionMarker(scope, params=None, autoactive=True)
|
||||||
|
|
||||||
def cached_property(f):
|
def cached_property(f):
|
||||||
|
@ -85,9 +74,9 @@ def pyobj_property(name):
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
group = parser.getgroup("general")
|
group = parser.getgroup("general")
|
||||||
group.addoption('--funcargs',
|
group.addoption('--fixtures', '--fixtures',
|
||||||
action="store_true", dest="showfuncargs", default=False,
|
action="store_true", dest="showfixtures", default=False,
|
||||||
help="show available function arguments, sorted by plugin")
|
help="show available fixtures, sorted by plugin appearance")
|
||||||
parser.addini("python_files", type="args",
|
parser.addini("python_files", type="args",
|
||||||
default=('test_*.py', '*_test.py'),
|
default=('test_*.py', '*_test.py'),
|
||||||
help="glob-style file patterns for Python test module discovery")
|
help="glob-style file patterns for Python test module discovery")
|
||||||
|
@ -97,8 +86,8 @@ def pytest_addoption(parser):
|
||||||
help="prefixes for Python test function and method discovery")
|
help="prefixes for Python test function and method discovery")
|
||||||
|
|
||||||
def pytest_cmdline_main(config):
|
def pytest_cmdline_main(config):
|
||||||
if config.option.showfuncargs:
|
if config.option.showfixtures:
|
||||||
showfuncargs(config)
|
showfixtures(config)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +108,7 @@ def pytest_configure(config):
|
||||||
)
|
)
|
||||||
|
|
||||||
def pytest_sessionstart(session):
|
def pytest_sessionstart(session):
|
||||||
session.funcargmanager = FuncargManager(session)
|
session._fixturemanager = FixtureManager(session)
|
||||||
|
|
||||||
@pytest.mark.trylast
|
@pytest.mark.trylast
|
||||||
def pytest_namespace():
|
def pytest_namespace():
|
||||||
|
@ -131,10 +120,11 @@ def pytest_namespace():
|
||||||
'collect': {
|
'collect': {
|
||||||
'Module': Module, 'Class': Class, 'Instance': Instance,
|
'Module': Module, 'Class': Class, 'Instance': Instance,
|
||||||
'Function': Function, 'Generator': Generator,
|
'Function': Function, 'Generator': Generator,
|
||||||
'_fillfuncargs': fillfuncargs}
|
'_fillfuncargs': fillfixtures}
|
||||||
}
|
}
|
||||||
|
|
||||||
def pytest_funcarg__pytestconfig(request):
|
@fixture()
|
||||||
|
def pytestconfig(request):
|
||||||
""" the pytest config object with access to command line opts."""
|
""" the pytest config object with access to command line opts."""
|
||||||
return request.config
|
return request.config
|
||||||
|
|
||||||
|
@ -146,12 +136,12 @@ def pytest_pyfunc_call(__multicall__, pyfuncitem):
|
||||||
testfunction(*pyfuncitem._args)
|
testfunction(*pyfuncitem._args)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
funcargnames = pyfuncitem.funcargnames
|
fixturenames = pyfuncitem.fixturenames
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
funcargs = pyfuncitem.funcargs
|
funcargs = pyfuncitem.funcargs
|
||||||
else:
|
else:
|
||||||
funcargs = {}
|
funcargs = {}
|
||||||
for name in funcargnames:
|
for name in fixturenames:
|
||||||
funcargs[name] = pyfuncitem.funcargs[name]
|
funcargs[name] = pyfuncitem.funcargs[name]
|
||||||
testfunction(**funcargs)
|
testfunction(**funcargs)
|
||||||
|
|
||||||
|
@ -352,7 +342,7 @@ class Module(pytest.File, PyCollector):
|
||||||
return self._memoizedcall('_obj', self._importtestmodule)
|
return self._memoizedcall('_obj', self._importtestmodule)
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
self.session.funcargmanager._parsefactories(self.obj, self.nodeid)
|
self.session._fixturemanager._parsefactories(self.obj, self.nodeid)
|
||||||
return super(Module, self).collect()
|
return super(Module, self).collect()
|
||||||
|
|
||||||
def _importtestmodule(self):
|
def _importtestmodule(self):
|
||||||
|
@ -425,7 +415,7 @@ class Instance(PyCollector):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
self.session.funcargmanager._parsefactories(self.obj, self.nodeid)
|
self.session._fixturemanager._parsefactories(self.obj, self.nodeid)
|
||||||
return super(Instance, self).collect()
|
return super(Instance, self).collect()
|
||||||
|
|
||||||
def newinstance(self):
|
def newinstance(self):
|
||||||
|
@ -534,14 +524,14 @@ def hasinit(obj):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def fillfuncargs(function):
|
def fillfixtures(function):
|
||||||
""" fill missing funcargs for a test function. """
|
""" fill missing funcargs for a test function. """
|
||||||
if getattr(function, "_args", None) is None: # not a yielded function
|
if getattr(function, "_args", None) is None: # not a yielded function
|
||||||
try:
|
try:
|
||||||
request = function._request
|
request = function._request
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
request = function._request = FuncargRequest(function)
|
request = function._request = FixtureRequest(function)
|
||||||
request._fillfuncargs()
|
request._fillfixtures()
|
||||||
|
|
||||||
_notexists = object()
|
_notexists = object()
|
||||||
|
|
||||||
|
@ -605,21 +595,30 @@ class CallSpec2(object):
|
||||||
self._globalparam = param
|
self._globalparam = param
|
||||||
|
|
||||||
|
|
||||||
class Metafunc:
|
class FuncargnamesCompatAttr:
|
||||||
|
""" helper class so that Metafunc, Function and FixtureRequest
|
||||||
|
don't need to each define the "funcargnames" compatibility attribute.
|
||||||
|
"""
|
||||||
|
@property
|
||||||
|
def funcargnames(self):
|
||||||
|
""" alias attribute for ``fixturenames`` for pre-2.3 compatibility"""
|
||||||
|
return self.fixturenames
|
||||||
|
|
||||||
|
class Metafunc(FuncargnamesCompatAttr):
|
||||||
def __init__(self, function, config=None, cls=None, module=None,
|
def __init__(self, function, config=None, cls=None, module=None,
|
||||||
parentnode=None):
|
parentnode=None):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.module = module
|
self.module = module
|
||||||
self.function = function
|
self.function = function
|
||||||
self.parentnode = parentnode
|
self.parentnode = parentnode
|
||||||
self.parentid = getattr(parentnode, "nodeid", "")
|
self._parentid = getattr(parentnode, "nodeid", "")
|
||||||
argnames = getfuncargnames(function, startindex=int(cls is not None))
|
argnames = getfuncargnames(function, startindex=int(cls is not None))
|
||||||
if parentnode is not None:
|
if parentnode is not None:
|
||||||
fm = parentnode.session.funcargmanager
|
fm = parentnode.session._fixturemanager
|
||||||
self.funcargnames, self._arg2facdeflist = fm.getallfuncargnames(
|
self.fixturenames, self._arg2fixturedeflist = fm.getfixtureclosure(
|
||||||
argnames, parentnode)
|
argnames, parentnode)
|
||||||
else:
|
else:
|
||||||
self.funcargnames = argnames
|
self.fixturenames = argnames
|
||||||
self.cls = cls
|
self.cls = cls
|
||||||
self.module = module
|
self.module = module
|
||||||
self._calls = []
|
self._calls = []
|
||||||
|
@ -631,7 +630,7 @@ class Metafunc:
|
||||||
""" Add new invocations to the underlying test function using the list
|
""" Add new invocations to the underlying test function using the list
|
||||||
of argvalues for the given argnames. Parametrization is performed
|
of argvalues for the given argnames. Parametrization is performed
|
||||||
during the collection phase. If you need to setup expensive resources
|
during the collection phase. If you need to setup expensive resources
|
||||||
you may pass indirect=True and implement a funcarg factory which can
|
you may pass indirect=True and implement a fixture function which can
|
||||||
perform the expensive setup just before a test is actually run.
|
perform the expensive setup just before a test is actually run.
|
||||||
|
|
||||||
:arg argnames: an argument name or a list of argument names
|
:arg argnames: an argument name or a list of argument names
|
||||||
|
@ -640,7 +639,7 @@ class Metafunc:
|
||||||
values for the list of argument names.
|
values for the list of argument names.
|
||||||
|
|
||||||
:arg indirect: if True each argvalue corresponding to an argument will
|
:arg indirect: if True each argvalue corresponding to an argument will
|
||||||
be passed as request.param to its respective funcarg factory so
|
be passed as request.param to its respective fixture function so
|
||||||
that it can perform more expensive setups during the setup phase of
|
that it can perform more expensive setups during the setup phase of
|
||||||
a test rather than at collection time.
|
a test rather than at collection time.
|
||||||
|
|
||||||
|
@ -657,7 +656,7 @@ class Metafunc:
|
||||||
if not indirect:
|
if not indirect:
|
||||||
#XXX should we also check for the opposite case?
|
#XXX should we also check for the opposite case?
|
||||||
for arg in argnames:
|
for arg in argnames:
|
||||||
if arg not in self.funcargnames:
|
if arg not in self.fixturenames:
|
||||||
raise ValueError("%r has no argument %r" %(self.function, arg))
|
raise ValueError("%r has no argument %r" %(self.function, arg))
|
||||||
valtype = indirect and "params" or "funcargs"
|
valtype = indirect and "params" or "funcargs"
|
||||||
if not ids:
|
if not ids:
|
||||||
|
@ -686,13 +685,13 @@ class Metafunc:
|
||||||
:arg id: used for reporting and identification purposes. If you
|
:arg id: used for reporting and identification purposes. If you
|
||||||
don't supply an `id` an automatic unique id will be generated.
|
don't supply an `id` an automatic unique id will be generated.
|
||||||
|
|
||||||
:arg param: a parameter which will be exposed to a later funcarg factory
|
:arg param: a parameter which will be exposed to a later fixture function
|
||||||
invocation through the ``request.param`` attribute.
|
invocation through the ``request.param`` attribute.
|
||||||
"""
|
"""
|
||||||
assert funcargs is None or isinstance(funcargs, dict)
|
assert funcargs is None or isinstance(funcargs, dict)
|
||||||
if funcargs is not None:
|
if funcargs is not None:
|
||||||
for name in funcargs:
|
for name in funcargs:
|
||||||
if name not in self.funcargnames:
|
if name not in self.fixturenames:
|
||||||
pytest.fail("funcarg %r not used in this function." % name)
|
pytest.fail("funcarg %r not used in this function." % name)
|
||||||
else:
|
else:
|
||||||
funcargs = {}
|
funcargs = {}
|
||||||
|
@ -722,11 +721,11 @@ class IDMaker:
|
||||||
return "-".join(l)
|
return "-".join(l)
|
||||||
|
|
||||||
|
|
||||||
def showfuncargs(config):
|
def showfixtures(config):
|
||||||
from _pytest.main import wrap_session
|
from _pytest.main import wrap_session
|
||||||
return wrap_session(config, _showfuncargs_main)
|
return wrap_session(config, _showfixtures_main)
|
||||||
|
|
||||||
def _showfuncargs_main(config, session):
|
def _showfixtures_main(config, session):
|
||||||
session.perform_collect()
|
session.perform_collect()
|
||||||
if session.items:
|
if session.items:
|
||||||
plugins = session.items[0].getplugins()
|
plugins = session.items[0].getplugins()
|
||||||
|
@ -735,7 +734,7 @@ def _showfuncargs_main(config, session):
|
||||||
curdir = py.path.local()
|
curdir = py.path.local()
|
||||||
tw = py.io.TerminalWriter()
|
tw = py.io.TerminalWriter()
|
||||||
verbose = config.getvalue("verbose")
|
verbose = config.getvalue("verbose")
|
||||||
argprefix = session.funcargmanager._argprefix
|
argprefix = session._fixturemanager._argprefix
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
available = []
|
available = []
|
||||||
for name, factory in vars(plugin).items():
|
for name, factory in vars(plugin).items():
|
||||||
|
@ -854,7 +853,7 @@ class RaisesContext(object):
|
||||||
# the basic py.test Function item
|
# the basic py.test Function item
|
||||||
#
|
#
|
||||||
_dummy = object()
|
_dummy = object()
|
||||||
class Function(FunctionMixin, pytest.Item):
|
class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
|
||||||
""" a Function Item is responsible for setting up and executing a
|
""" a Function Item is responsible for setting up and executing a
|
||||||
Python test function.
|
Python test function.
|
||||||
"""
|
"""
|
||||||
|
@ -876,11 +875,11 @@ class Function(FunctionMixin, pytest.Item):
|
||||||
self.param = callspec.param
|
self.param = callspec.param
|
||||||
else:
|
else:
|
||||||
self.funcargs = {}
|
self.funcargs = {}
|
||||||
self._request = req = FuncargRequest(self)
|
self._request = req = FixtureRequest(self)
|
||||||
#req._discoverfactories()
|
#req._discoverfactories()
|
||||||
if callobj is not _dummy:
|
if callobj is not _dummy:
|
||||||
self.obj = callobj
|
self.obj = callobj
|
||||||
self.funcargnames = self._getfixturenames()
|
self.fixturenames = self._getfuncargnames()
|
||||||
|
|
||||||
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
|
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
|
||||||
setattr(self.markers, name, val)
|
setattr(self.markers, name, val)
|
||||||
|
@ -888,9 +887,10 @@ class Function(FunctionMixin, pytest.Item):
|
||||||
for name, val in keywords.items():
|
for name, val in keywords.items():
|
||||||
setattr(self.markers, name, val)
|
setattr(self.markers, name, val)
|
||||||
|
|
||||||
def _getfixturenames(self):
|
|
||||||
|
def _getfuncargnames(self):
|
||||||
startindex = int(self.cls is not None)
|
startindex = int(self.cls is not None)
|
||||||
return (self.session.funcargmanager._autofixtures +
|
return (self.session._fixturemanager._autofixtures +
|
||||||
getfuncargnames(self.obj, startindex=startindex))
|
getfuncargnames(self.obj, startindex=startindex))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -921,7 +921,7 @@ class Function(FunctionMixin, pytest.Item):
|
||||||
super(Function, self).setup()
|
super(Function, self).setup()
|
||||||
#if hasattr(self, "_request"):
|
#if hasattr(self, "_request"):
|
||||||
# self._request._callsetup()
|
# self._request._callsetup()
|
||||||
fillfuncargs(self)
|
fillfixtures(self)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
try:
|
try:
|
||||||
|
@ -960,8 +960,8 @@ def scopeproperty(name=None, doc=None):
|
||||||
return decoratescope
|
return decoratescope
|
||||||
|
|
||||||
|
|
||||||
class FuncargRequest:
|
class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
""" A request for function arguments from a test or setup function.
|
""" A request for fixtures from a test or setup function.
|
||||||
|
|
||||||
A request object gives access to attributes of the requesting
|
A request object gives access to attributes of the requesting
|
||||||
test context. It has an optional ``param`` attribute in case
|
test context. It has an optional ``param`` attribute in case
|
||||||
|
@ -976,38 +976,38 @@ class FuncargRequest:
|
||||||
self.scope = "function"
|
self.scope = "function"
|
||||||
self.getparent = pyfuncitem.getparent
|
self.getparent = pyfuncitem.getparent
|
||||||
self._funcargs = self._pyfuncitem.funcargs.copy()
|
self._funcargs = self._pyfuncitem.funcargs.copy()
|
||||||
self._name2factory = {}
|
self._arg2fixturedeflist = {}
|
||||||
self.funcargmanager = pyfuncitem.session.funcargmanager
|
self._fixturemanager = pyfuncitem.session._fixturemanager
|
||||||
self._currentarg = None
|
self._currentarg = None
|
||||||
self.parentid = pyfuncitem.parent.nodeid
|
self._parentid = pyfuncitem.parent.nodeid
|
||||||
self.funcargnames, self._arg2facdeflist_ = \
|
self.fixturenames, self._arg2fixturedeflist_ = \
|
||||||
self.funcargmanager.getallfuncargnames(
|
self._fixturemanager.getfixtureclosure(
|
||||||
getfuncargnames(self.function), # XXX _pyfuncitem...
|
getfuncargnames(self.function), # XXX _pyfuncitem...
|
||||||
pyfuncitem.parent)
|
pyfuncitem.parent)
|
||||||
self._factorystack = []
|
self._fixturestack = []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def node(self):
|
def node(self):
|
||||||
""" underlying collection node (depends on request scope)"""
|
""" underlying collection node (depends on request scope)"""
|
||||||
return self._getscopeitem(self.scope)
|
return self._getscopeitem(self.scope)
|
||||||
|
|
||||||
def _getfaclist(self, argname):
|
def _getfixturedeflist(self, argname):
|
||||||
facdeflist = self._name2factory.get(argname, None)
|
fixturedeflist = self._arg2fixturedeflist.get(argname, None)
|
||||||
getfactb = None
|
getfixturetb = None
|
||||||
function = None
|
function = None
|
||||||
if facdeflist is None:
|
if fixturedeflist is None:
|
||||||
if self._factorystack:
|
if self._fixturestack:
|
||||||
function = self._factorystack[-1].func
|
function = self._fixturestack[-1].func
|
||||||
getfactb = lambda: self._factorystack[:-1]
|
getfixturetb = lambda: self._fixturestack[:-1]
|
||||||
else:
|
else:
|
||||||
function = self.function
|
function = self.function
|
||||||
facdeflist = self.funcargmanager.getfactorylist(
|
fixturedeflist = self._fixturemanager.getfixturedeflist(
|
||||||
argname, self.parentid)
|
argname, self._parentid)
|
||||||
self._name2factory[argname] = facdeflist
|
self._arg2fixturedeflist[argname] = fixturedeflist
|
||||||
if not facdeflist:
|
if not fixturedeflist:
|
||||||
self.funcargmanager._raiselookupfailed(argname, function,
|
self._fixturemanager._raiselookupfailed(argname, function,
|
||||||
self.parentid, getfactb)
|
self._parentid, getfixturetb)
|
||||||
return facdeflist
|
return fixturedeflist
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def config(self):
|
def config(self):
|
||||||
|
@ -1060,7 +1060,7 @@ class FuncargRequest:
|
||||||
"""add finalizer/teardown function to be called after the
|
"""add finalizer/teardown function to be called after the
|
||||||
last test within the requesting test context finished
|
last test within the requesting test context finished
|
||||||
execution. """
|
execution. """
|
||||||
# XXX usually this method is shadowed by factorydef specific ones
|
# XXX usually this method is shadowed by fixturedef specific ones
|
||||||
self._addfinalizer(finalizer, scope=self.scope)
|
self._addfinalizer(finalizer, scope=self.scope)
|
||||||
|
|
||||||
def _addfinalizer(self, finalizer, scope):
|
def _addfinalizer(self, finalizer, scope):
|
||||||
|
@ -1084,15 +1084,15 @@ class FuncargRequest:
|
||||||
self.node.applymarker(marker)
|
self.node.applymarker(marker)
|
||||||
|
|
||||||
def raiseerror(self, msg):
|
def raiseerror(self, msg):
|
||||||
""" raise a FuncargLookupError with the given message. """
|
""" raise a FixtureLookupError with the given message. """
|
||||||
raise self.funcargmanager.FuncargLookupError(self.function, msg)
|
raise self._fixturemanager.FixtureLookupError(self.function, msg)
|
||||||
|
|
||||||
|
|
||||||
def _fillfuncargs(self):
|
def _fillfixtures(self):
|
||||||
item = self._pyfuncitem
|
item = self._pyfuncitem
|
||||||
funcargnames = getattr(item, "funcargnames", self.funcargnames)
|
fixturenames = getattr(item, "fixturenames", self.fixturenames)
|
||||||
|
|
||||||
for argname in funcargnames:
|
for argname in fixturenames:
|
||||||
if argname not in item.funcargs:
|
if argname not in item.funcargs:
|
||||||
item.funcargs[argname] = self.getfuncargvalue(argname)
|
item.funcargs[argname] = self.getfuncargvalue(argname)
|
||||||
|
|
||||||
|
@ -1100,9 +1100,9 @@ class FuncargRequest:
|
||||||
""" (deprecated) Return a testing resource managed by ``setup`` &
|
""" (deprecated) Return a testing resource managed by ``setup`` &
|
||||||
``teardown`` calls. ``scope`` and ``extrakey`` determine when the
|
``teardown`` calls. ``scope`` and ``extrakey`` determine when the
|
||||||
``teardown`` function will be called so that subsequent calls to
|
``teardown`` function will be called so that subsequent calls to
|
||||||
``setup`` would recreate the resource. With pytest-2.3 you
|
``setup`` would recreate the resource. With pytest-2.3 you often
|
||||||
do not need ``cached_setup()`` as you can directly declare a scope
|
do not need ``cached_setup()`` as you can directly declare a scope
|
||||||
on a funcarg factory and register a finalizer through
|
on a fixture function and register a finalizer through
|
||||||
``request.addfinalizer()``.
|
``request.addfinalizer()``.
|
||||||
|
|
||||||
:arg teardown: function receiving a previously setup resource.
|
:arg teardown: function receiving a previously setup resource.
|
||||||
|
@ -1151,27 +1151,27 @@ class FuncargRequest:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
factorydeflist = self._getfaclist(argname)
|
fixturedeflist = self._getfixturedeflist(argname)
|
||||||
except FuncargLookupError:
|
except FixtureLookupError:
|
||||||
if argname == "request":
|
if argname == "request":
|
||||||
return self
|
return self
|
||||||
raise
|
raise
|
||||||
factorydef = factorydeflist.pop()
|
fixturedef = fixturedeflist.pop()
|
||||||
self._factorystack.append(factorydef)
|
self._fixturestack.append(fixturedef)
|
||||||
try:
|
try:
|
||||||
result = self._getfuncargvalue(factorydef)
|
result = self._getfuncargvalue(fixturedef)
|
||||||
self._funcargs[argname] = result
|
self._funcargs[argname] = result
|
||||||
return result
|
return result
|
||||||
finally:
|
finally:
|
||||||
self._factorystack.pop()
|
self._fixturestack.pop()
|
||||||
|
|
||||||
def _getfuncargvalue(self, factorydef):
|
def _getfuncargvalue(self, fixturedef):
|
||||||
if factorydef.active:
|
if fixturedef.active:
|
||||||
return factorydef.cached_result
|
return fixturedef.cached_result
|
||||||
|
|
||||||
# prepare request scope and param attributes before
|
# prepare request scope and param attributes before
|
||||||
# calling into factory
|
# calling into factory
|
||||||
argname = factorydef.argname
|
argname = fixturedef.argname
|
||||||
node = self._pyfuncitem
|
node = self._pyfuncitem
|
||||||
mp = monkeypatch()
|
mp = monkeypatch()
|
||||||
mp.setattr(self, '_currentarg', argname)
|
mp.setattr(self, '_currentarg', argname)
|
||||||
|
@ -1181,7 +1181,7 @@ class FuncargRequest:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
mp.setattr(self, 'param', param, raising=False)
|
mp.setattr(self, 'param', param, raising=False)
|
||||||
scope = factorydef.scope
|
scope = fixturedef.scope
|
||||||
if scope is not None:
|
if scope is not None:
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
if scopemismatch(self.scope, scope):
|
if scopemismatch(self.scope, scope):
|
||||||
|
@ -1195,20 +1195,20 @@ class FuncargRequest:
|
||||||
mp.setattr(self, "scope", scope)
|
mp.setattr(self, "scope", scope)
|
||||||
|
|
||||||
# prepare finalization according to scope
|
# prepare finalization according to scope
|
||||||
self.session._setupstate.addfinalizer(factorydef.finish, self.node)
|
self.session._setupstate.addfinalizer(fixturedef.finish, self.node)
|
||||||
self.funcargmanager.addargfinalizer(factorydef.finish, argname)
|
self._fixturemanager.addargfinalizer(fixturedef.finish, argname)
|
||||||
for subargname in factorydef.funcargnames: # XXX all deps?
|
for subargname in fixturedef.fixturenames: # XXX all deps?
|
||||||
self.funcargmanager.addargfinalizer(factorydef.finish, subargname)
|
self._fixturemanager.addargfinalizer(fixturedef.finish, subargname)
|
||||||
mp.setattr(self, "addfinalizer", factorydef.addfinalizer)
|
mp.setattr(self, "addfinalizer", fixturedef.addfinalizer)
|
||||||
# finally perform the factory call
|
# finally perform the factory call
|
||||||
val = factorydef.execute(request=self)
|
val = fixturedef.execute(request=self)
|
||||||
mp.undo()
|
mp.undo()
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def _factorytraceback(self):
|
def _factorytraceback(self):
|
||||||
lines = []
|
lines = []
|
||||||
for factorydef in self._factorystack:
|
for fixturedef in self._fixturestack:
|
||||||
factory = factorydef.func
|
factory = fixturedef.func
|
||||||
fs, lineno = getfslineno(factory)
|
fs, lineno = getfslineno(factory)
|
||||||
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
|
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
|
||||||
args = inspect.formatargspec(*inspect.getargspec(factory))
|
args = inspect.formatargspec(*inspect.getargspec(factory))
|
||||||
|
@ -1232,10 +1232,10 @@ class FuncargRequest:
|
||||||
raise ValueError("unknown finalization scope %r" %(scope,))
|
raise ValueError("unknown finalization scope %r" %(scope,))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<FuncargRequest for %r>" %(self._pyfuncitem)
|
return "<FixtureRequest for %r>" %(self._pyfuncitem)
|
||||||
|
|
||||||
class ScopeMismatchError(Exception):
|
class ScopeMismatchError(Exception):
|
||||||
""" A funcarg factory tries to access a funcargvalue/factory
|
""" A fixture function tries to use a different fixture function which
|
||||||
which has a lower scope (e.g. a Session one calls a function one)
|
which has a lower scope (e.g. a Session one calls a function one)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1249,14 +1249,14 @@ def slice_kwargs(names, kwargs):
|
||||||
new_kwargs[name] = kwargs[name]
|
new_kwargs[name] = kwargs[name]
|
||||||
return new_kwargs
|
return new_kwargs
|
||||||
|
|
||||||
class FuncargLookupError(LookupError):
|
class FixtureLookupError(LookupError):
|
||||||
""" could not find a factory. """
|
""" could not find a factory. """
|
||||||
def __init__(self, function, msg, factblines=None):
|
def __init__(self, function, msg, factblines=None):
|
||||||
self.function = function
|
self.function = function
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
self.factblines = factblines
|
self.factblines = factblines
|
||||||
|
|
||||||
class FuncargLookupErrorRepr(TerminalRepr):
|
class FixtureLookupErrorRepr(TerminalRepr):
|
||||||
def __init__(self, filename, firstlineno, deflines, errorstring, factblines):
|
def __init__(self, filename, firstlineno, deflines, errorstring, factblines):
|
||||||
self.deflines = deflines
|
self.deflines = deflines
|
||||||
self.errorstring = errorstring
|
self.errorstring = errorstring
|
||||||
|
@ -1268,10 +1268,10 @@ class FuncargLookupErrorRepr(TerminalRepr):
|
||||||
tw.line()
|
tw.line()
|
||||||
if self.factblines:
|
if self.factblines:
|
||||||
tw.line(' dependency of:')
|
tw.line(' dependency of:')
|
||||||
for factorydef in self.factblines:
|
for fixturedef in self.factblines:
|
||||||
tw.line(' %s in %s' % (
|
tw.line(' %s in %s' % (
|
||||||
factorydef.argname,
|
fixturedef.argname,
|
||||||
factorydef.baseid,
|
fixturedef.baseid,
|
||||||
))
|
))
|
||||||
tw.line()
|
tw.line()
|
||||||
for line in self.deflines:
|
for line in self.deflines:
|
||||||
|
@ -1281,15 +1281,15 @@ class FuncargLookupErrorRepr(TerminalRepr):
|
||||||
tw.line()
|
tw.line()
|
||||||
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
||||||
|
|
||||||
class FuncargManager:
|
class FixtureManager:
|
||||||
_argprefix = "pytest_funcarg__"
|
_argprefix = "pytest_funcarg__"
|
||||||
FuncargLookupError = FuncargLookupError
|
FixtureLookupError = FixtureLookupError
|
||||||
FuncargLookupErrorRepr = FuncargLookupErrorRepr
|
FixtureLookupErrorRepr = FixtureLookupErrorRepr
|
||||||
|
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
self.session = session
|
self.session = session
|
||||||
self.config = session.config
|
self.config = session.config
|
||||||
self.arg2facspec = {}
|
self.arg2fixturedeflist = {}
|
||||||
self._seenplugins = set()
|
self._seenplugins = set()
|
||||||
self._holderobjseen = set()
|
self._holderobjseen = set()
|
||||||
self._arg2finish = {}
|
self._arg2finish = {}
|
||||||
|
@ -1319,41 +1319,44 @@ class FuncargManager:
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
self.pytest_plugin_registered(plugin)
|
self.pytest_plugin_registered(plugin)
|
||||||
|
|
||||||
def getallfuncargnames(self, funcargnames, parentnode):
|
def getfixtureclosure(self, fixturenames, parentnode):
|
||||||
# collect the closure of all funcargs, starting with
|
# collect the closure of all funcargs, starting with the given
|
||||||
# funcargnames as the initial set
|
# fixturenames as the initial set. As we have to visit all
|
||||||
# we populate and return a arg2facdeflist mapping
|
# factory definitions anyway, we also return a arg2fixturedeflist
|
||||||
# so that the caller can reuse it and does not have to re-discover
|
# mapping so that the caller can reuse it and does not have
|
||||||
# factories again for each funcargname
|
# to re-discover fixturedefs again for each fixturename
|
||||||
|
# (discovering matching fixtures for a given name/node is expensive)
|
||||||
|
|
||||||
parentid = parentnode.nodeid
|
parentid = parentnode.nodeid
|
||||||
funcargnames = self._autofixtures + list(funcargnames)
|
fixturenames_closure = list(self._autofixtures)
|
||||||
def merge(otherlist):
|
def merge(otherlist):
|
||||||
for arg in otherlist:
|
for arg in otherlist:
|
||||||
if arg not in funcargnames:
|
if arg not in fixturenames_closure:
|
||||||
funcargnames.append(arg)
|
fixturenames_closure.append(arg)
|
||||||
arg2facdeflist = {}
|
merge(fixturenames)
|
||||||
|
arg2fixturedeflist = {}
|
||||||
lastlen = -1
|
lastlen = -1
|
||||||
while lastlen != len(funcargnames):
|
while lastlen != len(fixturenames_closure):
|
||||||
lastlen = len(funcargnames)
|
lastlen = len(fixturenames_closure)
|
||||||
for argname in list(funcargnames):
|
for argname in fixturenames_closure:
|
||||||
if argname in arg2facdeflist:
|
if argname in arg2fixturedeflist:
|
||||||
continue
|
continue
|
||||||
facdeflist = self.getfactorylist(argname, parentid)
|
fixturedeflist = self.getfixturedeflist(argname, parentid)
|
||||||
arg2facdeflist[argname] = facdeflist
|
arg2fixturedeflist[argname] = fixturedeflist
|
||||||
if facdeflist is not None:
|
if fixturedeflist is not None:
|
||||||
for facdef in facdeflist:
|
for fixturedef in fixturedeflist:
|
||||||
merge(facdef.funcargnames)
|
merge(fixturedef.fixturenames)
|
||||||
return funcargnames, arg2facdeflist
|
return fixturenames_closure, arg2fixturedeflist
|
||||||
|
|
||||||
def pytest_generate_tests(self, metafunc):
|
def pytest_generate_tests(self, metafunc):
|
||||||
for argname in metafunc.funcargnames:
|
for argname in metafunc.fixturenames:
|
||||||
faclist = metafunc._arg2facdeflist[argname]
|
faclist = metafunc._arg2fixturedeflist[argname]
|
||||||
if faclist is None:
|
if faclist is None:
|
||||||
continue # will raise FuncargLookupError at setup time
|
continue # will raise FixtureLookupError at setup time
|
||||||
for facdef in faclist:
|
for fixturedef in faclist:
|
||||||
if facdef.params is not None:
|
if fixturedef.params is not None:
|
||||||
metafunc.parametrize(argname, facdef.params, indirect=True,
|
metafunc.parametrize(argname, fixturedef.params, indirect=True,
|
||||||
scope=facdef.scope)
|
scope=fixturedef.scope)
|
||||||
|
|
||||||
def pytest_collection_modifyitems(self, items):
|
def pytest_collection_modifyitems(self, items):
|
||||||
# separate parametrized setups
|
# separate parametrized setups
|
||||||
|
@ -1394,7 +1397,7 @@ class FuncargManager:
|
||||||
obj = getattr(holderobj, name)
|
obj = getattr(holderobj, name)
|
||||||
if not callable(obj):
|
if not callable(obj):
|
||||||
continue
|
continue
|
||||||
# fixture functions have a pytest_funcarg__ prefix
|
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
|
||||||
# or are "@pytest.fixture" marked
|
# or are "@pytest.fixture" marked
|
||||||
marker = getattr(obj, "_pytestfixturefunction", None)
|
marker = getattr(obj, "_pytestfixturefunction", None)
|
||||||
if marker is None:
|
if marker is None:
|
||||||
|
@ -1408,42 +1411,42 @@ class FuncargManager:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
assert not name.startswith(self._argprefix)
|
assert not name.startswith(self._argprefix)
|
||||||
factorydef = FactoryDef(self, nodeid, name, obj,
|
fixturedef = FixtureDef(self, nodeid, name, obj,
|
||||||
marker.scope, marker.params,
|
marker.scope, marker.params,
|
||||||
unittest=unittest)
|
unittest=unittest)
|
||||||
faclist = self.arg2facspec.setdefault(name, [])
|
faclist = self.arg2fixturedeflist.setdefault(name, [])
|
||||||
faclist.append(factorydef)
|
faclist.append(fixturedef)
|
||||||
if marker.autoactive:
|
if marker.autoactive:
|
||||||
# make sure the self._autofixtures list is always sorted
|
# make sure the self._autofixtures list is always sorted
|
||||||
# by scope, scopenum 0 is session
|
# by scope, scopenum 0 is session
|
||||||
self._autofixtures.append(name)
|
self._autofixtures.append(name)
|
||||||
self._autofixtures.sort(
|
self._autofixtures.sort(
|
||||||
key=lambda x: self.arg2facspec[x][-1].scopenum)
|
key=lambda x: self.arg2fixturedeflist[x][-1].scopenum)
|
||||||
|
|
||||||
def getfactorylist(self, argname, nodeid):
|
def getfixturedeflist(self, argname, nodeid):
|
||||||
try:
|
try:
|
||||||
factorydeflist = self.arg2facspec[argname]
|
fixturedeflist = self.arg2fixturedeflist[argname]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return list(self._matchfactories(factorydeflist, nodeid))
|
return list(self._matchfactories(fixturedeflist, nodeid))
|
||||||
|
|
||||||
def _matchfactories(self, factorydeflist, nodeid):
|
def _matchfactories(self, fixturedeflist, nodeid):
|
||||||
for factorydef in factorydeflist:
|
for fixturedef in fixturedeflist:
|
||||||
if nodeid.startswith(factorydef.baseid):
|
if nodeid.startswith(fixturedef.baseid):
|
||||||
yield factorydef
|
yield fixturedef
|
||||||
|
|
||||||
def _raiselookupfailed(self, argname, function, nodeid, getfactb=None):
|
def _raiselookupfailed(self, argname, function, nodeid, getfixturetb=None):
|
||||||
available = []
|
available = []
|
||||||
for name, facdef in self.arg2facspec.items():
|
for name, fixturedef in self.arg2fixturedeflist.items():
|
||||||
faclist = list(self._matchfactories(facdef, nodeid))
|
faclist = list(self._matchfactories(fixturedef, nodeid))
|
||||||
if faclist:
|
if faclist:
|
||||||
available.append(name)
|
available.append(name)
|
||||||
msg = "LookupError: no factory found for argument %r" % (argname,)
|
msg = "LookupError: no factory found for argument %r" % (argname,)
|
||||||
msg += "\n available funcargs: %s" %(", ".join(available),)
|
msg += "\n available funcargs: %s" %(", ".join(available),)
|
||||||
msg += "\n use 'py.test --funcargs [testpath]' for help on them."
|
msg += "\n use 'py.test --fixtures [testpath]' for help on them."
|
||||||
lines = getfactb and getfactb() or []
|
lines = getfixturetb and getfixturetb() or []
|
||||||
raise FuncargLookupError(function, msg, lines)
|
raise FixtureLookupError(function, msg, lines)
|
||||||
|
|
||||||
def addargfinalizer(self, finalizer, argname):
|
def addargfinalizer(self, finalizer, argname):
|
||||||
l = self._arg2finish.setdefault(argname, [])
|
l = self._arg2finish.setdefault(argname, [])
|
||||||
|
@ -1456,11 +1459,11 @@ class FuncargManager:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class FactoryDef:
|
class FixtureDef:
|
||||||
""" A container for a factory definition. """
|
""" A container for a factory definition. """
|
||||||
def __init__(self, funcargmanager, baseid, argname, func, scope, params,
|
def __init__(self, fixturenanager, baseid, argname, func, scope, params,
|
||||||
unittest=False):
|
unittest=False):
|
||||||
self.funcargmanager = funcargmanager
|
self._fixturemanager = fixturenanager
|
||||||
self.baseid = baseid
|
self.baseid = baseid
|
||||||
self.func = func
|
self.func = func
|
||||||
self.argname = argname
|
self.argname = argname
|
||||||
|
@ -1468,7 +1471,7 @@ class FactoryDef:
|
||||||
self.scopenum = scopes.index(scope or "function")
|
self.scopenum = scopes.index(scope or "function")
|
||||||
self.params = params
|
self.params = params
|
||||||
startindex = unittest and 1 or None
|
startindex = unittest and 1 or None
|
||||||
self.funcargnames = getfuncargnames(func, startindex=startindex)
|
self.fixturenames = getfuncargnames(func, startindex=startindex)
|
||||||
self.unittest = unittest
|
self.unittest = unittest
|
||||||
self.active = False
|
self.active = False
|
||||||
self._finalizer = []
|
self._finalizer = []
|
||||||
|
@ -1481,14 +1484,14 @@ class FactoryDef:
|
||||||
func = self._finalizer.pop()
|
func = self._finalizer.pop()
|
||||||
func()
|
func()
|
||||||
# check neccesity of next commented call
|
# check neccesity of next commented call
|
||||||
self.funcargmanager.removefinalizer(self.finish)
|
self._fixturemanager.removefinalizer(self.finish)
|
||||||
self.active = False
|
self.active = False
|
||||||
#print "finished", self
|
#print "finished", self
|
||||||
#del self.cached_result
|
#del self.cached_result
|
||||||
|
|
||||||
def execute(self, request):
|
def execute(self, request):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
for newname in self.funcargnames:
|
for newname in self.fixturenames:
|
||||||
kwargs[newname] = request.getfuncargvalue(newname)
|
kwargs[newname] = request.getfuncargvalue(newname)
|
||||||
if self.unittest:
|
if self.unittest:
|
||||||
result = self.func(request.instance, **kwargs)
|
result = self.func(request.instance, **kwargs)
|
||||||
|
@ -1499,7 +1502,7 @@ class FactoryDef:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<FactoryDef name=%r scope=%r>" % (self.argname, self.scope)
|
return "<FixtureDef name=%r scope=%r>" % (self.argname, self.scope)
|
||||||
|
|
||||||
def getfuncargnames(function, startindex=None):
|
def getfuncargnames(function, startindex=None):
|
||||||
# XXX merge with main.py's varnames
|
# XXX merge with main.py's varnames
|
||||||
|
|
|
@ -21,7 +21,7 @@ def pytest_pycollect_makeitem(collector, name, obj):
|
||||||
|
|
||||||
class UnitTestCase(pytest.Class):
|
class UnitTestCase(pytest.Class):
|
||||||
def collect(self):
|
def collect(self):
|
||||||
self.session.funcargmanager._parsefactories(self.obj, self.nodeid,
|
self.session._fixturemanager._parsefactories(self.obj, self.nodeid,
|
||||||
unittest=True)
|
unittest=True)
|
||||||
loader = py.std.unittest.TestLoader()
|
loader = py.std.unittest.TestLoader()
|
||||||
module = self.getparent(pytest.Module).obj
|
module = self.getparent(pytest.Module).obj
|
||||||
|
@ -52,8 +52,8 @@ class UnitTestCase(pytest.Class):
|
||||||
class TestCaseFunction(pytest.Function):
|
class TestCaseFunction(pytest.Function):
|
||||||
_excinfo = None
|
_excinfo = None
|
||||||
|
|
||||||
def _getfixturenames(self):
|
def _getfuncargnames(self):
|
||||||
return list(self.session.funcargmanager._autofixtures)
|
return list(self.session._fixturemanager._autofixtures)
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self._testcase = self.parent.obj(self.name)
|
self._testcase = self.parent.obj(self.name)
|
||||||
|
@ -65,7 +65,7 @@ class TestCaseFunction(pytest.Function):
|
||||||
if hasattr(self._testcase, 'setup_method'):
|
if hasattr(self._testcase, 'setup_method'):
|
||||||
self._testcase.setup_method(self._obj)
|
self._testcase.setup_method(self._obj)
|
||||||
if hasattr(self, "_request"):
|
if hasattr(self, "_request"):
|
||||||
self._request._fillfuncargs()
|
self._request._fillfixtures()
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
if hasattr(self._testcase, 'teardown_method'):
|
if hasattr(self._testcase, 'teardown_method'):
|
||||||
|
|
|
@ -25,7 +25,7 @@ Builtin resources / function arguments
|
||||||
You can ask for available builtin or project-custom
|
You can ask for available builtin or project-custom
|
||||||
:ref:`function arguments <funcargs>` by typing::
|
:ref:`function arguments <funcargs>` by typing::
|
||||||
|
|
||||||
$ py.test --funcargs
|
$ py.test --fixtures
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||||
|
|
|
@ -15,7 +15,7 @@ def test_generative(param1, param2):
|
||||||
assert param1 * 2 < param2
|
assert param1 * 2 < param2
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'param1' in metafunc.funcargnames:
|
if 'param1' in metafunc.fixturenames:
|
||||||
metafunc.addcall(funcargs=dict(param1=3, param2=6))
|
metafunc.addcall(funcargs=dict(param1=3, param2=6))
|
||||||
|
|
||||||
class TestFailing(object):
|
class TestFailing(object):
|
||||||
|
|
|
@ -13,9 +13,9 @@ example: specifying and selecting acceptance tests
|
||||||
help="run (slow) acceptance tests")
|
help="run (slow) acceptance tests")
|
||||||
|
|
||||||
def pytest_funcarg__accept(request):
|
def pytest_funcarg__accept(request):
|
||||||
return AcceptFuncarg(request)
|
return AcceptFixture(request)
|
||||||
|
|
||||||
class AcceptFuncarg:
|
class AcceptFixture:
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
if not request.config.option.acceptance:
|
if not request.config.option.acceptance:
|
||||||
pytest.skip("specify -A to run acceptance tests")
|
pytest.skip("specify -A to run acceptance tests")
|
||||||
|
@ -39,7 +39,7 @@ and the actual test function example:
|
||||||
If you run this test without specifying a command line option
|
If you run this test without specifying a command line option
|
||||||
the test will get skipped with an appropriate message. Otherwise
|
the test will get skipped with an appropriate message. Otherwise
|
||||||
you can start to add convenience and test support methods
|
you can start to add convenience and test support methods
|
||||||
to your AcceptFuncarg and drive running of tools or
|
to your AcceptFixture and drive running of tools or
|
||||||
applications and provide ways to do assertions about
|
applications and provide ways to do assertions about
|
||||||
the output.
|
the output.
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ Now we add a test configuration like this::
|
||||||
help="run all combinations")
|
help="run all combinations")
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'param1' in metafunc.funcargnames:
|
if 'param1' in metafunc.fixturenames:
|
||||||
if metafunc.config.option.all:
|
if metafunc.config.option.all:
|
||||||
end = 5
|
end = 5
|
||||||
else:
|
else:
|
||||||
|
@ -213,7 +213,7 @@ creates a database object for the actual test invocations::
|
||||||
# content of conftest.py
|
# content of conftest.py
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'db' in metafunc.funcargnames:
|
if 'db' in metafunc.fixturenames:
|
||||||
metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
|
metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
|
||||||
|
|
||||||
class DB1:
|
class DB1:
|
||||||
|
|
|
@ -126,11 +126,11 @@ the ``MYARG`` function argument.
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
With pytest-2.3 you can use the :ref:`@pytest.fixture` decorator
|
With pytest-2.3 you can use the :ref:`@pytest.fixture` decorator
|
||||||
to mark a function as a funcarg factory.
|
to mark a function as a fixture function.
|
||||||
|
|
||||||
.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
|
.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
|
||||||
|
|
||||||
Can I yield multiple values from a funcarg factory function?
|
Can I yield multiple values from a fixture function function?
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
There are two conceptual reasons why yielding from a factory function
|
There are two conceptual reasons why yielding from a factory function
|
||||||
|
|
|
@ -676,6 +676,6 @@ and provides methods to:
|
||||||
* to add finalizers/teardowns to be invoked when the last
|
* to add finalizers/teardowns to be invoked when the last
|
||||||
test of the requesting test context executes
|
test of the requesting test context executes
|
||||||
|
|
||||||
.. autoclass:: _pytest.python.FuncargRequest()
|
.. autoclass:: _pytest.python.FixtureRequest()
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ There are several limitations and difficulties with this approach:
|
||||||
4. there is no way how you can make use of funcarg factories
|
4. there is no way how you can make use of funcarg factories
|
||||||
in xUnit setup methods.
|
in xUnit setup methods.
|
||||||
|
|
||||||
5. A non-parametrized funcarg factory cannot use a parametrized
|
5. A non-parametrized fixture function cannot use a parametrized
|
||||||
funcarg resource if it isn't stated in the test function signature.
|
funcarg resource if it isn't stated in the test function signature.
|
||||||
|
|
||||||
All of these limitations are addressed with pytest-2.3 and its
|
All of these limitations are addressed with pytest-2.3 and its
|
||||||
|
|
|
@ -29,7 +29,7 @@ different variants of test resources to test with.
|
||||||
The basic mechanism for injecting objects is called the *funcarg
|
The basic mechanism for injecting objects is called the *funcarg
|
||||||
mechanism* because objects are injected when a test or setup
|
mechanism* because objects are injected when a test or setup
|
||||||
**function** states it as an **argument**. The injected argument
|
**function** states it as an **argument**. The injected argument
|
||||||
is created by a call to a registered **funcarg factory** for each argument
|
is created by a call to a registered **fixture function** for each argument
|
||||||
name. This mechanism is an example of `Dependency Injection`_
|
name. This mechanism is an example of `Dependency Injection`_
|
||||||
and helps to de-couple test code from the setup of required
|
and helps to de-couple test code from the setup of required
|
||||||
objects: at test writing time you do not need to care for the details of
|
objects: at test writing time you do not need to care for the details of
|
||||||
|
@ -38,7 +38,7 @@ shared on a per-class, module or session basis, or if your test function
|
||||||
is invoked multiple times with differently configured resource
|
is invoked multiple times with differently configured resource
|
||||||
instances.
|
instances.
|
||||||
|
|
||||||
Funcarg dependency injection allows to organise test resources
|
Fixture dependency injection allows to organise test resources
|
||||||
in a modular explicit way so that test functions state their needs
|
in a modular explicit way so that test functions state their needs
|
||||||
in their signature. pytest additionally offers powerful xunit-style
|
in their signature. pytest additionally offers powerful xunit-style
|
||||||
:ref:`setup functions <setup functions>` for the cases where you need
|
:ref:`setup functions <setup functions>` for the cases where you need
|
||||||
|
@ -144,7 +144,7 @@ with a list of available function arguments.
|
||||||
|
|
||||||
You can always issue::
|
You can always issue::
|
||||||
|
|
||||||
py.test --funcargs test_simplefactory.py
|
py.test --fixtures test_simplefactory.py
|
||||||
|
|
||||||
to see available function arguments.
|
to see available function arguments.
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ that option::
|
||||||
help="run all combinations")
|
help="run all combinations")
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'param1' in metafunc.funcargnames:
|
if 'param1' in metafunc.fixturenames:
|
||||||
if metafunc.config.option.all:
|
if metafunc.config.option.all:
|
||||||
end = 5
|
end = 5
|
||||||
else:
|
else:
|
||||||
|
@ -336,7 +336,7 @@ They help to inspect a testfunction and to generate tests
|
||||||
according to test configuration or values specified
|
according to test configuration or values specified
|
||||||
in the class or module where a test function is defined:
|
in the class or module where a test function is defined:
|
||||||
|
|
||||||
``metafunc.funcargnames``: set of required function arguments for given function
|
``metafunc.fixturenames``: set of required function arguments for given function
|
||||||
|
|
||||||
``metafunc.function``: underlying python test function
|
``metafunc.function``: underlying python test function
|
||||||
|
|
||||||
|
@ -346,6 +346,8 @@ in the class or module where a test function is defined:
|
||||||
|
|
||||||
``metafunc.config``: access to command line opts and general config
|
``metafunc.config``: access to command line opts and general config
|
||||||
|
|
||||||
|
``metafunc.funcargnames``: alias for ``fixturenames``, for pre-2.3 compatibility
|
||||||
|
|
||||||
.. automethod:: Metafunc.parametrize
|
.. automethod:: Metafunc.parametrize
|
||||||
.. automethod:: Metafunc.addcall(funcargs=None,id=_notexists,param=_notexists)
|
.. automethod:: Metafunc.addcall(funcargs=None,id=_notexists,param=_notexists)
|
||||||
|
|
||||||
|
@ -360,7 +362,7 @@ in the class or module where a test function is defined:
|
||||||
Compatibility notes
|
Compatibility notes
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
**Funcargs** were originally introduced to pytest-2.0. In pytest-2.3
|
**Fixtures** were originally introduced to pytest-2.0. In pytest-2.3
|
||||||
the mechanism was extended and refined:
|
the mechanism was extended and refined:
|
||||||
|
|
||||||
* previously funcarg factories were specified with a special
|
* previously funcarg factories were specified with a special
|
||||||
|
@ -376,14 +378,14 @@ the mechanism was extended and refined:
|
||||||
|
|
||||||
* if you used parametrization and funcarg factories which made use of
|
* if you used parametrization and funcarg factories which made use of
|
||||||
``request.cached_setup()`` it is recommeneded to invest a few minutes
|
``request.cached_setup()`` it is recommeneded to invest a few minutes
|
||||||
and simplify your funcarg factory code to use the `@pytest.fixture`_
|
and simplify your fixture function code to use the `@pytest.fixture`_
|
||||||
decorator instead. This will also allow to take advantage of
|
decorator instead. This will also allow to take advantage of
|
||||||
the `automatic per-resource grouping`_ of tests.
|
the `automatic per-resource grouping`_ of tests.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Throughout the pytest documents the ``pytest_funcarg__NAME`` way of
|
Throughout the pytest documents the ``pytest_funcarg__NAME`` way of
|
||||||
defining a funcarg factory is often termed "old-style". Their
|
defining a fixture function is often termed "old-style". Their
|
||||||
use remains fully supported and existing code using it should run
|
use remains fully supported and existing code using it should run
|
||||||
unmodified.
|
unmodified.
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ was created. More info at :ref:`tmpdir handling`.
|
||||||
|
|
||||||
You can find out what kind of builtin :ref:`funcargs` exist by typing::
|
You can find out what kind of builtin :ref:`funcargs` exist by typing::
|
||||||
|
|
||||||
py.test --funcargs # shows builtin and custom function arguments
|
py.test --fixtures # shows builtin and custom function arguments
|
||||||
|
|
||||||
Where to go next
|
Where to go next
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
|
@ -24,7 +24,7 @@ command line options
|
||||||
traceback print mode (long/short/line/no).
|
traceback print mode (long/short/line/no).
|
||||||
``--fulltrace``
|
``--fulltrace``
|
||||||
don't cut any tracebacks (default is to cut).
|
don't cut any tracebacks (default is to cut).
|
||||||
``--funcargs``
|
``--fixtures``
|
||||||
show available function arguments, sorted by plugin
|
show available function arguments, sorted by plugin
|
||||||
|
|
||||||
Start improving this plugin in 30 seconds
|
Start improving this plugin in 30 seconds
|
||||||
|
|
|
@ -26,7 +26,7 @@ Getting help on version, option names, environment variables
|
||||||
::
|
::
|
||||||
|
|
||||||
py.test --version # shows where pytest was imported from
|
py.test --version # shows where pytest was imported from
|
||||||
py.test --funcargs # show available builtin function arguments
|
py.test --fixtures # show available builtin function arguments
|
||||||
py.test -h | --help # show help on command line and config file options
|
py.test -h | --help # show help on command line and config file options
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ Python インタープリターの対話モードから次のように入力す
|
||||||
|
|
||||||
次のように入力して、利用できる組み込みまたはプロジェクトカスタムの :ref:`関数の引数 <funcargs>` を確認できます。
|
次のように入力して、利用できる組み込みまたはプロジェクトカスタムの :ref:`関数の引数 <funcargs>` を確認できます。
|
||||||
|
|
||||||
| $ py.test --funcargs
|
| $ py.test --fixtures
|
||||||
| ====================== test session starts =======================
|
| ====================== test session starts =======================
|
||||||
| platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
| platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||||
| collected 0 items
|
| collected 0 items
|
||||||
|
@ -98,7 +98,7 @@ Python インタープリターの対話モードから次のように入力す
|
||||||
| ======================== in 0.00 seconds ========================
|
| ======================== in 0.00 seconds ========================
|
||||||
|
|
||||||
..
|
..
|
||||||
$ py.test --funcargs
|
$ py.test --fixtures
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||||
collected 0 items
|
collected 0 items
|
||||||
|
|
|
@ -15,7 +15,7 @@ def test_generative(param1, param2):
|
||||||
assert param1 * 2 < param2
|
assert param1 * 2 < param2
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'param1' in metafunc.funcargnames:
|
if 'param1' in metafunc.fixturenames:
|
||||||
metafunc.addcall(funcargs=dict(param1=3, param2=6))
|
metafunc.addcall(funcargs=dict(param1=3, param2=6))
|
||||||
|
|
||||||
class TestFailing(object):
|
class TestFailing(object):
|
||||||
|
|
|
@ -13,9 +13,9 @@ example: specifying and selecting acceptance tests
|
||||||
help="run (slow) acceptance tests")
|
help="run (slow) acceptance tests")
|
||||||
|
|
||||||
def pytest_funcarg__accept(request):
|
def pytest_funcarg__accept(request):
|
||||||
return AcceptFuncarg(request)
|
return AcceptFixture(request)
|
||||||
|
|
||||||
class AcceptFuncarg:
|
class AcceptFixture:
|
||||||
def __init__(self, request):
|
def __init__(self, request):
|
||||||
if not request.config.option.acceptance:
|
if not request.config.option.acceptance:
|
||||||
pytest.skip("specify -A to run acceptance tests")
|
pytest.skip("specify -A to run acceptance tests")
|
||||||
|
@ -39,7 +39,7 @@ and the actual test function example:
|
||||||
If you run this test without specifying a command line option
|
If you run this test without specifying a command line option
|
||||||
the test will get skipped with an appropriate message. Otherwise
|
the test will get skipped with an appropriate message. Otherwise
|
||||||
you can start to add convenience and test support methods
|
you can start to add convenience and test support methods
|
||||||
to your AcceptFuncarg and drive running of tools or
|
to your AcceptFixture and drive running of tools or
|
||||||
applications and provide ways to do assertions about
|
applications and provide ways to do assertions about
|
||||||
the output.
|
the output.
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ def pytest_generate_tests(metafunc):
|
||||||
# over the python interpreters of our list above - the actual
|
# over the python interpreters of our list above - the actual
|
||||||
# setup and lookup of interpreters in the python1/python2 factories
|
# setup and lookup of interpreters in the python1/python2 factories
|
||||||
# respectively.
|
# respectively.
|
||||||
for arg in metafunc.funcargnames:
|
for arg in metafunc.fixturenames:
|
||||||
if arg in ("python1", "python2"):
|
if arg in ("python1", "python2"):
|
||||||
metafunc.parametrize(arg, pythonlist, indirect=True)
|
metafunc.parametrize(arg, pythonlist, indirect=True)
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ py.test は、簡単にパラメーターをテスト関数へ渡せます。パ
|
||||||
help="run all combinations")
|
help="run all combinations")
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'param1' in metafunc.funcargnames:
|
if 'param1' in metafunc.fixturenames:
|
||||||
if metafunc.config.option.all:
|
if metafunc.config.option.all:
|
||||||
end = 5
|
end = 5
|
||||||
else:
|
else:
|
||||||
|
@ -266,7 +266,7 @@ Robert Collins による標準ライブラリの unittest フレームワーク
|
||||||
# conftest.py の内容
|
# conftest.py の内容
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if 'db' in metafunc.funcargnames:
|
if 'db' in metafunc.fixturenames:
|
||||||
metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
|
metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
|
||||||
|
|
||||||
class DB1:
|
class DB1:
|
||||||
|
|
|
@ -153,7 +153,7 @@ funcarg ファクトリー関数から複数の値を yield できますか?
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
..
|
..
|
||||||
Can I yield multiple values from a funcarg factory function?
|
Can I yield multiple values from a fixture function function?
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
|
@ -157,7 +157,7 @@ py.test には :ref:`builtinfuncargs` が付属していて、そのサンプル
|
||||||
|
|
||||||
いつでも次のようにして::
|
いつでも次のようにして::
|
||||||
|
|
||||||
py.test --funcargs test_simplefactory.py
|
py.test --fixtures test_simplefactory.py
|
||||||
|
|
||||||
..
|
..
|
||||||
to see available function arguments (which you can also
|
to see available function arguments (which you can also
|
||||||
|
@ -171,7 +171,7 @@ py.test には :ref:`builtinfuncargs` が付属していて、そのサンプル
|
||||||
.. _`xUnit style`: xunit_setup.html
|
.. _`xUnit style`: xunit_setup.html
|
||||||
|
|
||||||
|
|
||||||
.. _`funcarg factory`:
|
.. _`fixture function`:
|
||||||
.. _factory:
|
.. _factory:
|
||||||
|
|
||||||
funcarg **request** オブジェクト
|
funcarg **request** オブジェクト
|
||||||
|
@ -182,24 +182,24 @@ funcarg **request** オブジェクト
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
..
|
..
|
||||||
Each funcarg factory receives a **request** object tied to a specific test
|
Each fixture function receives a **request** object tied to a specific test
|
||||||
function call. A request object is passed to a funcarg factory and provides
|
function call. A request object is passed to a fixture function and provides
|
||||||
access to test configuration and context:
|
access to test configuration and context:
|
||||||
|
|
||||||
funcarg ファクトリー関数は、特別なテスト関数呼び出しに関連付けられた **request** オブジェクトを受け取ります。request オブジェクトは funcarg ファクトリーへ渡されて、テスト設定とコンテキストへのアクセスを提供します:
|
funcarg ファクトリー関数は、特別なテスト関数呼び出しに関連付けられた **request** オブジェクトを受け取ります。request オブジェクトは funcarg ファクトリーへ渡されて、テスト設定とコンテキストへのアクセスを提供します:
|
||||||
|
|
||||||
.. autoclass:: _pytest.python.FuncargRequest()
|
.. autoclass:: _pytest.python.FixtureRequest()
|
||||||
:members: function,cls,module,keywords,config
|
:members: function,cls,module,keywords,config
|
||||||
|
|
||||||
.. _`useful caching and finalization helpers`:
|
.. _`useful caching and finalization helpers`:
|
||||||
|
|
||||||
.. automethod:: FuncargRequest.addfinalizer
|
.. automethod:: FixtureRequest.addfinalizer
|
||||||
|
|
||||||
.. automethod:: FuncargRequest.cached_setup
|
.. automethod:: FixtureRequest.cached_setup
|
||||||
|
|
||||||
.. automethod:: FuncargRequest.applymarker
|
.. automethod:: FixtureRequest.applymarker
|
||||||
|
|
||||||
.. automethod:: FuncargRequest.getfuncargvalue
|
.. automethod:: FixtureRequest.getfuncargvalue
|
||||||
|
|
||||||
|
|
||||||
.. _`test generators`:
|
.. _`test generators`:
|
||||||
|
@ -236,7 +236,7 @@ funcarg ファクトリー関数は、特別なテスト関数呼び出しに関
|
||||||
|
|
||||||
# test_example.py の内容
|
# test_example.py の内容
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if "numiter" in metafunc.funcargnames:
|
if "numiter" in metafunc.fixturenames:
|
||||||
metafunc.parametrize("numiter", range(10))
|
metafunc.parametrize("numiter", range(10))
|
||||||
|
|
||||||
def test_func(numiter):
|
def test_func(numiter):
|
||||||
|
@ -329,9 +329,9 @@ funcarg ファクトリー関数は、特別なテスト関数呼び出しに関
|
||||||
metafunc オブジェクトは ``pytest_generate_tests`` フックへ渡されます。これはテスト関数を検査したり、テスト設定またはテスト関数が定義されているクラスやモジュールで指定された値を取るテストを生成するのに役立ちます:
|
metafunc オブジェクトは ``pytest_generate_tests`` フックへ渡されます。これはテスト関数を検査したり、テスト設定またはテスト関数が定義されているクラスやモジュールで指定された値を取るテストを生成するのに役立ちます:
|
||||||
|
|
||||||
..
|
..
|
||||||
``metafunc.funcargnames``: set of required function arguments for given function
|
``metafunc.fixturenames``: set of required function arguments for given function
|
||||||
|
|
||||||
``metafunc.funcargnames``: テスト関数へ渡される引数セット
|
``metafunc.fixturenames``: テスト関数へ渡される引数セット
|
||||||
|
|
||||||
..
|
..
|
||||||
``metafunc.function``: underlying python test function
|
``metafunc.function``: underlying python test function
|
||||||
|
|
|
@ -265,7 +265,7 @@ py.test は :ref:`標準的なテスト探索ルール <test discovery>` に従
|
||||||
|
|
||||||
組み込みの :ref:`funcargs` を把握するには、次のコマンドを実行します::
|
組み込みの :ref:`funcargs` を把握するには、次のコマンドを実行します::
|
||||||
|
|
||||||
py.test --funcargs # 組み込み/カスタムの関数の引数を表示する
|
py.test --fixtures # 組み込み/カスタムの関数の引数を表示する
|
||||||
|
|
||||||
..
|
..
|
||||||
Where to go next
|
Where to go next
|
||||||
|
|
|
@ -24,7 +24,7 @@ command line options
|
||||||
traceback print mode (long/short/line/no).
|
traceback print mode (long/short/line/no).
|
||||||
``--fulltrace``
|
``--fulltrace``
|
||||||
don't cut any tracebacks (default is to cut).
|
don't cut any tracebacks (default is to cut).
|
||||||
``--funcargs``
|
``--fixtures``
|
||||||
show available function arguments, sorted by plugin
|
show available function arguments, sorted by plugin
|
||||||
|
|
||||||
Start improving this plugin in 30 seconds
|
Start improving this plugin in 30 seconds
|
||||||
|
|
|
@ -43,7 +43,7 @@ Python 2.5 か、それ以上のバージョンを使っているなら、コマ
|
||||||
::
|
::
|
||||||
|
|
||||||
py.test --version # pytest がインポートされた場所を表示
|
py.test --version # pytest がインポートされた場所を表示
|
||||||
py.test --funcargs # 利用できる組み込みの関数引数を表示
|
py.test --fixtures # 利用できる組み込みの関数引数を表示
|
||||||
py.test -h | --help # コマンドラインと設定ファイルオプションのヘルプを表示
|
py.test -h | --help # コマンドラインと設定ファイルオプションのヘルプを表示
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
|
@ -64,7 +64,7 @@ def pytest_generate_tests(metafunc):
|
||||||
for name, l in multi.kwargs.items():
|
for name, l in multi.kwargs.items():
|
||||||
for val in l:
|
for val in l:
|
||||||
metafunc.addcall(funcargs={name: val})
|
metafunc.addcall(funcargs={name: val})
|
||||||
elif 'anypython' in metafunc.funcargnames:
|
elif 'anypython' in metafunc.fixturenames:
|
||||||
for name in ('python2.4', 'python2.5', 'python2.6',
|
for name in ('python2.4', 'python2.5', 'python2.6',
|
||||||
'python2.7', 'python3.1', 'pypy', 'jython'):
|
'python2.7', 'python3.1', 'pypy', 'jython'):
|
||||||
metafunc.addcall(id=name, param=name)
|
metafunc.addcall(id=name, param=name)
|
||||||
|
|
|
@ -363,7 +363,7 @@ class TestLoggingInteraction:
|
||||||
assert 'operation on closed file' not in result.stderr.str()
|
assert 'operation on closed file' not in result.stderr.str()
|
||||||
|
|
||||||
|
|
||||||
class TestCaptureFuncarg:
|
class TestCaptureFixture:
|
||||||
def test_std_functional(self, testdir):
|
def test_std_functional(self, testdir):
|
||||||
reprec = testdir.inline_runsource("""
|
reprec = testdir.inline_runsource("""
|
||||||
def test_hello(capsys):
|
def test_hello(capsys):
|
||||||
|
|
|
@ -2,7 +2,7 @@ import py, pytest
|
||||||
from _pytest.config import Conftest
|
from _pytest.config import Conftest
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if "basedir" in metafunc.funcargnames:
|
if "basedir" in metafunc.fixturenames:
|
||||||
metafunc.addcall(param="global")
|
metafunc.addcall(param="global")
|
||||||
metafunc.addcall(param="inpackage")
|
metafunc.addcall(param="inpackage")
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ def test_help(testdir):
|
||||||
*setup.cfg*
|
*setup.cfg*
|
||||||
*minversion*
|
*minversion*
|
||||||
*to see*markers*py.test --markers*
|
*to see*markers*py.test --markers*
|
||||||
*to see*funcargs*py.test --funcargs*
|
*to see*fixtures*py.test --fixtures*
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_collectattr():
|
def test_collectattr():
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pytest, py, sys
|
import pytest, py, sys
|
||||||
from _pytest import python as funcargs
|
from _pytest import python as funcargs
|
||||||
from _pytest.python import FuncargLookupError
|
from _pytest.python import FixtureLookupError
|
||||||
|
|
||||||
class TestModule:
|
class TestModule:
|
||||||
def test_failing_import(self, testdir):
|
def test_failing_import(self, testdir):
|
||||||
|
@ -276,10 +276,10 @@ class TestFunction:
|
||||||
assert hasattr(modcol.obj, 'test_func')
|
assert hasattr(modcol.obj, 'test_func')
|
||||||
|
|
||||||
def test_function_equality(self, testdir, tmpdir):
|
def test_function_equality(self, testdir, tmpdir):
|
||||||
from _pytest.python import FuncargManager
|
from _pytest.python import FixtureManager
|
||||||
config = testdir.parseconfigure()
|
config = testdir.parseconfigure()
|
||||||
session = testdir.Session(config)
|
session = testdir.Session(config)
|
||||||
session.funcargmanager = FuncargManager(session)
|
session._fixturemanager = FixtureManager(session)
|
||||||
def func1():
|
def func1():
|
||||||
pass
|
pass
|
||||||
def func2():
|
def func2():
|
||||||
|
@ -542,10 +542,10 @@ def test_getfuncargnames():
|
||||||
pass
|
pass
|
||||||
assert funcargs.getfuncargnames(A) == ["x"]
|
assert funcargs.getfuncargnames(A) == ["x"]
|
||||||
|
|
||||||
class TestFillFuncArgs:
|
class TestFillFixtures:
|
||||||
def test_fillfuncargs_exposed(self):
|
def test_fillfuncargs_exposed(self):
|
||||||
# used by oejskit
|
# used by oejskit, kept for compatibility
|
||||||
assert pytest._fillfuncargs == funcargs.fillfuncargs
|
assert pytest._fillfuncargs == funcargs.fillfixtures
|
||||||
|
|
||||||
def test_funcarg_lookupfails(self, testdir):
|
def test_funcarg_lookupfails(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
@ -572,7 +572,7 @@ class TestFillFuncArgs:
|
||||||
def test_func(some, other):
|
def test_func(some, other):
|
||||||
pass
|
pass
|
||||||
""")
|
""")
|
||||||
funcargs.fillfuncargs(item)
|
funcargs.fillfixtures(item)
|
||||||
assert len(item.funcargs) == 2
|
assert len(item.funcargs) == 2
|
||||||
assert item.funcargs['some'] == "test_func"
|
assert item.funcargs['some'] == "test_func"
|
||||||
assert item.funcargs['other'] == 42
|
assert item.funcargs['other'] == 42
|
||||||
|
@ -611,7 +611,7 @@ class TestRequest:
|
||||||
def pytest_funcarg__something(request): pass
|
def pytest_funcarg__something(request): pass
|
||||||
def test_func(something): pass
|
def test_func(something): pass
|
||||||
""")
|
""")
|
||||||
req = funcargs.FuncargRequest(item)
|
req = funcargs.FixtureRequest(item)
|
||||||
assert req.function == item.obj
|
assert req.function == item.obj
|
||||||
assert req.keywords == item.keywords
|
assert req.keywords == item.keywords
|
||||||
assert hasattr(req.module, 'test_func')
|
assert hasattr(req.module, 'test_func')
|
||||||
|
@ -632,7 +632,7 @@ class TestRequest:
|
||||||
assert req.cls.__name__ == "TestB"
|
assert req.cls.__name__ == "TestB"
|
||||||
assert req.instance.__class__ == req.cls
|
assert req.instance.__class__ == req.cls
|
||||||
|
|
||||||
def XXXtest_request_contains_funcarg_name2factory(self, testdir):
|
def XXXtest_request_contains_funcarg_arg2fixturedeflist(self, testdir):
|
||||||
modcol = testdir.getmodulecol("""
|
modcol = testdir.getmodulecol("""
|
||||||
def pytest_funcarg__something(request):
|
def pytest_funcarg__something(request):
|
||||||
pass
|
pass
|
||||||
|
@ -642,9 +642,9 @@ class TestRequest:
|
||||||
""")
|
""")
|
||||||
item1, = testdir.genitems([modcol])
|
item1, = testdir.genitems([modcol])
|
||||||
assert item1.name == "test_method"
|
assert item1.name == "test_method"
|
||||||
name2factory = funcargs.FuncargRequest(item1)._name2factory
|
arg2fixturedeflist = funcargs.FixtureRequest(item1)._arg2fixturedeflist
|
||||||
assert len(name2factory) == 1
|
assert len(arg2fixturedeflist) == 1
|
||||||
assert name2factory[0].__name__ == "pytest_funcarg__something"
|
assert arg2fixturedeflist[0].__name__ == "pytest_funcarg__something"
|
||||||
|
|
||||||
def test_getfuncargvalue_recursive(self, testdir):
|
def test_getfuncargvalue_recursive(self, testdir):
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
|
@ -669,7 +669,7 @@ class TestRequest:
|
||||||
def test_func(something): pass
|
def test_func(something): pass
|
||||||
""")
|
""")
|
||||||
req = item._request
|
req = item._request
|
||||||
pytest.raises(FuncargLookupError, req.getfuncargvalue, "notexists")
|
pytest.raises(FixtureLookupError, req.getfuncargvalue, "notexists")
|
||||||
val = req.getfuncargvalue("something")
|
val = req.getfuncargvalue("something")
|
||||||
assert val == 1
|
assert val == 1
|
||||||
val = req.getfuncargvalue("something")
|
val = req.getfuncargvalue("something")
|
||||||
|
@ -717,7 +717,7 @@ class TestRequest:
|
||||||
def test_request_getmodulepath(self, testdir):
|
def test_request_getmodulepath(self, testdir):
|
||||||
modcol = testdir.getmodulecol("def test_somefunc(): pass")
|
modcol = testdir.getmodulecol("def test_somefunc(): pass")
|
||||||
item, = testdir.genitems([modcol])
|
item, = testdir.genitems([modcol])
|
||||||
req = funcargs.FuncargRequest(item)
|
req = funcargs.FixtureRequest(item)
|
||||||
assert req.fspath == modcol.fspath
|
assert req.fspath == modcol.fspath
|
||||||
|
|
||||||
class TestMarking:
|
class TestMarking:
|
||||||
|
@ -731,7 +731,7 @@ class TestMarking:
|
||||||
def test_func2(self, something):
|
def test_func2(self, something):
|
||||||
pass
|
pass
|
||||||
""")
|
""")
|
||||||
req1 = funcargs.FuncargRequest(item1)
|
req1 = funcargs.FixtureRequest(item1)
|
||||||
assert 'xfail' not in item1.keywords
|
assert 'xfail' not in item1.keywords
|
||||||
req1.applymarker(pytest.mark.xfail)
|
req1.applymarker(pytest.mark.xfail)
|
||||||
assert 'xfail' in item1.keywords
|
assert 'xfail' in item1.keywords
|
||||||
|
@ -814,7 +814,7 @@ class TestRequestCachedSetup:
|
||||||
|
|
||||||
def test_request_cachedsetup_extrakey(self, testdir):
|
def test_request_cachedsetup_extrakey(self, testdir):
|
||||||
item1 = testdir.getitem("def test_func(): pass")
|
item1 = testdir.getitem("def test_func(): pass")
|
||||||
req1 = funcargs.FuncargRequest(item1)
|
req1 = funcargs.FixtureRequest(item1)
|
||||||
l = ["hello", "world"]
|
l = ["hello", "world"]
|
||||||
def setup():
|
def setup():
|
||||||
return l.pop()
|
return l.pop()
|
||||||
|
@ -829,7 +829,7 @@ class TestRequestCachedSetup:
|
||||||
|
|
||||||
def test_request_cachedsetup_cache_deletion(self, testdir):
|
def test_request_cachedsetup_cache_deletion(self, testdir):
|
||||||
item1 = testdir.getitem("def test_func(): pass")
|
item1 = testdir.getitem("def test_func(): pass")
|
||||||
req1 = funcargs.FuncargRequest(item1)
|
req1 = funcargs.FixtureRequest(item1)
|
||||||
l = []
|
l = []
|
||||||
def setup():
|
def setup():
|
||||||
l.append("setup")
|
l.append("setup")
|
||||||
|
@ -906,14 +906,14 @@ class TestMetafunc:
|
||||||
def test_no_funcargs(self, testdir):
|
def test_no_funcargs(self, testdir):
|
||||||
def function(): pass
|
def function(): pass
|
||||||
metafunc = funcargs.Metafunc(function)
|
metafunc = funcargs.Metafunc(function)
|
||||||
assert not metafunc.funcargnames
|
assert not metafunc.fixturenames
|
||||||
repr(metafunc._calls)
|
repr(metafunc._calls)
|
||||||
|
|
||||||
def test_function_basic(self):
|
def test_function_basic(self):
|
||||||
def func(arg1, arg2="qwe"): pass
|
def func(arg1, arg2="qwe"): pass
|
||||||
metafunc = funcargs.Metafunc(func)
|
metafunc = funcargs.Metafunc(func)
|
||||||
assert len(metafunc.funcargnames) == 1
|
assert len(metafunc.fixturenames) == 1
|
||||||
assert 'arg1' in metafunc.funcargnames
|
assert 'arg1' in metafunc.fixturenames
|
||||||
assert metafunc.function is func
|
assert metafunc.function is func
|
||||||
assert metafunc.cls is None
|
assert metafunc.cls is None
|
||||||
|
|
||||||
|
@ -1032,7 +1032,7 @@ class TestMetafunc:
|
||||||
def test_parametrize_functional(self, testdir):
|
def test_parametrize_functional(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
assert "test_parametrize_functional" in metafunc.parentid
|
assert "test_parametrize_functional" in metafunc._parentid
|
||||||
metafunc.parametrize('x', [1,2], indirect=True)
|
metafunc.parametrize('x', [1,2], indirect=True)
|
||||||
metafunc.parametrize('y', [2])
|
metafunc.parametrize('y', [2])
|
||||||
def pytest_funcarg__x(request):
|
def pytest_funcarg__x(request):
|
||||||
|
@ -1170,7 +1170,7 @@ class TestMetafuncFunctional:
|
||||||
def test_addcall_with_two_funcargs_generators(self, testdir):
|
def test_addcall_with_two_funcargs_generators(self, testdir):
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
assert "arg1" in metafunc.funcargnames
|
assert "arg1" in metafunc.fixturenames
|
||||||
metafunc.addcall(funcargs=dict(arg1=1, arg2=2))
|
metafunc.addcall(funcargs=dict(arg1=1, arg2=2))
|
||||||
""")
|
""")
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
|
@ -1213,7 +1213,7 @@ class TestMetafuncFunctional:
|
||||||
def test_noself_in_method(self, testdir):
|
def test_noself_in_method(self, testdir):
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
assert 'xyz' not in metafunc.funcargnames
|
assert 'xyz' not in metafunc.fixturenames
|
||||||
|
|
||||||
class TestHello:
|
class TestHello:
|
||||||
def test_hello(xyz):
|
def test_hello(xyz):
|
||||||
|
@ -1228,7 +1228,7 @@ class TestMetafuncFunctional:
|
||||||
def test_generate_plugin_and_module(self, testdir):
|
def test_generate_plugin_and_module(self, testdir):
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
assert "arg1" in metafunc.funcargnames
|
assert "arg1" in metafunc.fixturenames
|
||||||
metafunc.addcall(id="world", param=(2,100))
|
metafunc.addcall(id="world", param=(2,100))
|
||||||
""")
|
""")
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
|
@ -1342,7 +1342,7 @@ class TestMetafuncFunctional:
|
||||||
def test_parametrize_on_setup_arg(self, testdir):
|
def test_parametrize_on_setup_arg(self, testdir):
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
assert "arg1" in metafunc.funcargnames
|
assert "arg1" in metafunc.fixturenames
|
||||||
metafunc.parametrize("arg1", [1], indirect=True)
|
metafunc.parametrize("arg1", [1], indirect=True)
|
||||||
|
|
||||||
def pytest_funcarg__arg1(request):
|
def pytest_funcarg__arg1(request):
|
||||||
|
@ -1403,7 +1403,7 @@ def test_funcarg_non_pycollectobj(testdir): # rough jstests usage
|
||||||
clscol = rep.result[0]
|
clscol = rep.result[0]
|
||||||
clscol.obj = lambda arg1: None
|
clscol.obj = lambda arg1: None
|
||||||
clscol.funcargs = {}
|
clscol.funcargs = {}
|
||||||
funcargs.fillfuncargs(clscol)
|
funcargs.fillfixtures(clscol)
|
||||||
assert clscol.funcargs['arg1'] == 42
|
assert clscol.funcargs['arg1'] == 42
|
||||||
|
|
||||||
|
|
||||||
|
@ -1488,7 +1488,7 @@ class TestReportInfo:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_show_funcarg(testdir):
|
def test_show_funcarg(testdir):
|
||||||
result = testdir.runpytest("--funcargs")
|
result = testdir.runpytest("--fixtures")
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
"*tmpdir*",
|
"*tmpdir*",
|
||||||
"*temporary directory*",
|
"*temporary directory*",
|
||||||
|
@ -1669,7 +1669,7 @@ def test_issue117_sessionscopeteardown(testdir):
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class TestFuncargFactory:
|
class TestFixtureFactory:
|
||||||
def test_receives_funcargs(self, testdir):
|
def test_receives_funcargs(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -1809,7 +1809,7 @@ class TestResourceIntegrationFunctional:
|
||||||
"*test_function*advanced*FAILED",
|
"*test_function*advanced*FAILED",
|
||||||
])
|
])
|
||||||
|
|
||||||
class TestFuncargManager:
|
class TestFixtureManager:
|
||||||
def pytest_funcarg__testdir(self, request):
|
def pytest_funcarg__testdir(self, request):
|
||||||
testdir = request.getfuncargvalue("testdir")
|
testdir = request.getfuncargvalue("testdir")
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
|
@ -1817,7 +1817,7 @@ class TestFuncargManager:
|
||||||
return "conftest"
|
return "conftest"
|
||||||
|
|
||||||
def pytest_funcarg__fm(request):
|
def pytest_funcarg__fm(request):
|
||||||
return request.funcargmanager
|
return request._fixturemanager
|
||||||
|
|
||||||
def pytest_funcarg__item(request):
|
def pytest_funcarg__item(request):
|
||||||
return request._pyfuncitem
|
return request._pyfuncitem
|
||||||
|
@ -1828,7 +1828,7 @@ class TestFuncargManager:
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
def test_hello(item, fm):
|
def test_hello(item, fm):
|
||||||
for name in ("fm", "hello", "item"):
|
for name in ("fm", "hello", "item"):
|
||||||
faclist = fm.getfactorylist(name, item.nodeid)
|
faclist = fm.getfixturedeflist(name, item.nodeid)
|
||||||
assert len(faclist) == 1
|
assert len(faclist) == 1
|
||||||
fac = faclist[0]
|
fac = faclist[0]
|
||||||
assert fac.func.__name__ == "pytest_funcarg__" + name
|
assert fac.func.__name__ == "pytest_funcarg__" + name
|
||||||
|
@ -1844,7 +1844,7 @@ class TestFuncargManager:
|
||||||
def pytest_funcarg__hello(self, request):
|
def pytest_funcarg__hello(self, request):
|
||||||
return "class"
|
return "class"
|
||||||
def test_hello(self, item, fm):
|
def test_hello(self, item, fm):
|
||||||
faclist = fm.getfactorylist("hello", item.nodeid)
|
faclist = fm.getfixturedeflist("hello", item.nodeid)
|
||||||
print (faclist)
|
print (faclist)
|
||||||
assert len(faclist) == 3
|
assert len(faclist) == 3
|
||||||
assert faclist[0].func(item._request) == "conftest"
|
assert faclist[0].func(item._request) == "conftest"
|
||||||
|
@ -1870,7 +1870,7 @@ class TestSetupDiscovery:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def pytest_funcarg__fm(request):
|
def pytest_funcarg__fm(request):
|
||||||
return request.funcargmanager
|
return request._fixturemanager
|
||||||
|
|
||||||
def pytest_funcarg__item(request):
|
def pytest_funcarg__item(request):
|
||||||
return request._pyfuncitem
|
return request._pyfuncitem
|
||||||
|
@ -1919,11 +1919,11 @@ class TestSetupDiscovery:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_func1(request):
|
def test_func1(request):
|
||||||
assert "db" not in request.funcargnames
|
assert "db" not in request.fixturenames
|
||||||
|
|
||||||
@pytest.mark.needsdb
|
@pytest.mark.needsdb
|
||||||
def test_func2(request):
|
def test_func2(request):
|
||||||
assert "db" in request.funcargnames
|
assert "db" in request.fixturenames
|
||||||
""")
|
""")
|
||||||
reprec = testdir.inline_run("-s")
|
reprec = testdir.inline_run("-s")
|
||||||
reprec.assertoutcome(passed=2)
|
reprec.assertoutcome(passed=2)
|
||||||
|
@ -2105,7 +2105,7 @@ class TestSetupManagement:
|
||||||
reprec.assertoutcome(passed=5)
|
reprec.assertoutcome(passed=5)
|
||||||
|
|
||||||
|
|
||||||
class TestFuncargMarker:
|
class TestFixtureMarker:
|
||||||
def test_parametrize(self, testdir):
|
def test_parametrize(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -2686,7 +2686,7 @@ def test_setup_funcarg_order(testdir):
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
|
||||||
def test_request_funcargnames(testdir):
|
def test_request_fixturenames(testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
@ -2699,8 +2699,23 @@ def test_request_funcargnames(testdir):
|
||||||
def sarg(tmpdir):
|
def sarg(tmpdir):
|
||||||
pass
|
pass
|
||||||
def test_function(request, farg):
|
def test_function(request, farg):
|
||||||
assert set(request.funcargnames) == \
|
assert set(request.fixturenames) == \
|
||||||
set(["tmpdir", "sarg", "arg1", "request", "farg"])
|
set(["tmpdir", "sarg", "arg1", "request", "farg"])
|
||||||
""")
|
""")
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
def test_funcargnames_compatattr(testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
def pytest_generate_tests(metafunc):
|
||||||
|
assert metafunc.funcargnames == metafunc.fixturenames
|
||||||
|
def pytest_funcarg__fn(request):
|
||||||
|
assert request._pyfuncitem.funcargnames == \
|
||||||
|
request._pyfuncitem.fixturenames
|
||||||
|
return request.funcargnames, request.fixturenames
|
||||||
|
|
||||||
|
def test_hello(fn):
|
||||||
|
assert fn[0] == fn[1]
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Option:
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if "option" in metafunc.funcargnames:
|
if "option" in metafunc.fixturenames:
|
||||||
metafunc.addcall(id="default",
|
metafunc.addcall(id="default",
|
||||||
funcargs={'option': Option(verbose=False)})
|
funcargs={'option': Option(verbose=False)})
|
||||||
metafunc.addcall(id="verbose",
|
metafunc.addcall(id="verbose",
|
||||||
|
|
Loading…
Reference in New Issue