introduce the pytest_configure_funcargs hook for better control on funcarg instanciation/configuration
This commit is contained in:
parent
ea936213bc
commit
b6815538c5
|
@ -115,6 +115,9 @@ pytest_pyfunc_call.firstresult = True
|
|||
def pytest_generate_tests(metafunc):
|
||||
""" generate (multiple) parametrized calls to a test function."""
|
||||
|
||||
def pytest_configure_funcargs(request):
|
||||
""" configure funcargs """
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# generic runtest related hooks
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
|
@ -500,6 +500,16 @@ def fillfuncargs(function):
|
|||
request = FuncargRequest(pyfuncitem=function)
|
||||
request._fillfuncargs()
|
||||
|
||||
def pytest_configure_funcargs(request):
|
||||
argnames = getfuncargnames(request.function)
|
||||
if argnames:
|
||||
item = request._pyfuncitem
|
||||
assert not getattr(item, '_args', None), (
|
||||
"yielded functions cannot have funcargs")
|
||||
for argname in argnames:
|
||||
if argname not in item.funcargs:
|
||||
item.funcargs[argname] = request.getfuncargvalue(argname)
|
||||
|
||||
_notexists = object()
|
||||
class CallSpec:
|
||||
def __init__(self, funcargs, id, param):
|
||||
|
@ -621,14 +631,6 @@ class FuncargRequest:
|
|||
""" the file system path of the test module which collected this test. """
|
||||
return self._pyfuncitem.fspath
|
||||
|
||||
def _fillfuncargs(self):
|
||||
argnames = getfuncargnames(self.function)
|
||||
if argnames:
|
||||
assert not getattr(self._pyfuncitem, '_args', None), (
|
||||
"yielded functions cannot have funcargs")
|
||||
for argname in argnames:
|
||||
if argname not in self._pyfuncitem.funcargs:
|
||||
self._pyfuncitem.funcargs[argname] = self.getfuncargvalue(argname)
|
||||
|
||||
|
||||
def applymarker(self, marker):
|
||||
|
@ -700,6 +702,9 @@ class FuncargRequest:
|
|||
self._currentarg = oldarg
|
||||
return res
|
||||
|
||||
def _fillfuncargs(self):
|
||||
self.config.hook.pytest_configure_funcargs.pcall(self._plugins, request=self)
|
||||
|
||||
def _getscopeitem(self, scope):
|
||||
if scope == "function":
|
||||
return self._pyfuncitem
|
||||
|
|
|
@ -115,6 +115,9 @@ think of as "resources").
|
|||
.. _`funcarg factory`:
|
||||
.. _factory:
|
||||
|
||||
|
||||
|
||||
|
||||
The funcarg **request** object
|
||||
=============================================
|
||||
|
||||
|
@ -140,6 +143,16 @@ factory and provides access to test configuration and context:
|
|||
.. _`parametrizing-tests`:
|
||||
.. _`parametrized test functions`:
|
||||
|
||||
|
||||
Reconfiguring funcargs in a test's setup
|
||||
========================================
|
||||
|
||||
Sometimes there is need to do additional funcarg setup steps
|
||||
which are outside of the normal setup and involve more than just one funcarg.
|
||||
For that reason the ``pytest_configure_funcargs(request)`` hook
|
||||
is called to implement and extend the funcarg filling mechanism.
|
||||
|
||||
|
||||
Parametrizing multiple calls to a test function
|
||||
===========================================================
|
||||
|
||||
|
|
|
@ -606,6 +606,22 @@ class TestFillFuncArgs:
|
|||
fillfuncargs(item)
|
||||
assert len(item.funcargs) == 1
|
||||
|
||||
def test_configure_hook(self, testdir):
|
||||
item = testdir.getitem("def test_func(some, other=20): pass")
|
||||
class Provider:
|
||||
def pytest_funcarg__some(self, request):
|
||||
return []
|
||||
def pytest_configure_funcargs(self, request):
|
||||
request.getfuncargvalue('some').append(1)
|
||||
item.config.pluginmanager.register(Provider())
|
||||
if hasattr(item, '_args'):
|
||||
del item._args
|
||||
from _pytest.python import fillfuncargs
|
||||
fillfuncargs(item)
|
||||
assert len(item.funcargs) == 1
|
||||
assert item.funcargs['some'] == [1]
|
||||
|
||||
|
||||
class TestRequest:
|
||||
def test_request_attributes(self, testdir):
|
||||
item = testdir.getitem("""
|
||||
|
|
Loading…
Reference in New Issue