allow factory/setup-markers on classes, using their respective __init__ methods which can use the funcarg mechanism
This commit is contained in:
parent
a5e7e441d3
commit
6cb3281ddd
|
@ -1507,9 +1507,12 @@ class FactoryDef:
|
|||
|
||||
def getfuncargnames(function, startindex=None):
|
||||
# XXX merge with main.py's varnames
|
||||
argnames = py.std.inspect.getargs(py.code.getrawcode(function))[0]
|
||||
if startindex is None:
|
||||
startindex = py.std.inspect.ismethod(function) and 1 or 0
|
||||
if inspect.isclass(function):
|
||||
function = function.__init__
|
||||
startindex = 1
|
||||
elif startindex is None:
|
||||
startindex = inspect.ismethod(function) and 1 or 0
|
||||
argnames = inspect.getargs(py.code.getrawcode(function))[0]
|
||||
defaults = getattr(function, 'func_defaults',
|
||||
getattr(function, '__defaults__', None)) or ()
|
||||
numdefaults = len(defaults)
|
||||
|
|
|
@ -389,19 +389,16 @@ object ``app`` and stick the ``smtp`` resource into it like this::
|
|||
|
||||
import pytest
|
||||
|
||||
class App:
|
||||
@pytest.factory(scope="module")
|
||||
class app:
|
||||
def __init__(self, smtp):
|
||||
self.smtp = smtp
|
||||
|
||||
@pytest.factory(scope="module")
|
||||
def app(smtp):
|
||||
return App(smtp)
|
||||
|
||||
def test_exists(app):
|
||||
assert app.smtp
|
||||
|
||||
Here we define the factory local to the test module and make it access
|
||||
the ``smtp`` resource by listing it as an input parameter. Let's run this::
|
||||
Here we declare an ``app`` class to be a factory and have its init-method
|
||||
use the previously defined ``smtp`` resource. Let's run it::
|
||||
|
||||
$ py.test -v test_appsetup.py
|
||||
=========================== test session starts ============================
|
||||
|
@ -418,7 +415,7 @@ the ``smtp`` resource by listing it as an input parameter. Let's run this::
|
|||
Due to the parametrization of ``smtp`` the test will run twice with two
|
||||
different ``App`` instances and respective smtp servers. There is no
|
||||
need for the ``app`` factory to be aware of the parametrization. Note
|
||||
that the ``app`` factory has a scope of ``module`` whereas it uses the
|
||||
that the ``app`` factory has a scope of ``module`` but uses the
|
||||
session-scoped ``smtp`` object: it is fine for factories to use
|
||||
"broader" scoped resources but not the other way round. A
|
||||
session-scoped resource could not use a module-scoped resource in a
|
||||
|
@ -498,8 +495,8 @@ Let's run the tests in verbose mode and with looking at the print-output::
|
|||
fin mod2
|
||||
|
||||
You can see that the parametrized module-scoped ``modarg`` resource caused
|
||||
a re-ordering of test execution. The finalizer for the ``mod1`` parametrized
|
||||
resource was executed before the ``mod2`` resource was setup.
|
||||
an ordering of test execution that lead to the fewest possible "active" resources. The finalizer for the ``mod1`` parametrized resource was executed
|
||||
before the ``mod2`` resource was setup.
|
||||
|
||||
.. currentmodule:: _pytest.python
|
||||
.. _`request`:
|
||||
|
@ -520,7 +517,6 @@ The ``request`` object may be received by `@pytest.factory`_ or
|
|||
* to add finalizers/teardowns to be invoked when the last
|
||||
test of the requesting test context executes
|
||||
|
||||
|
||||
.. autoclass:: _pytest.python.FuncargRequest()
|
||||
:members:
|
||||
|
||||
|
|
|
@ -535,6 +535,11 @@ def test_getfuncargnames():
|
|||
if sys.version_info < (3,0):
|
||||
assert funcargs.getfuncargnames(A.f) == ['arg1']
|
||||
|
||||
class A:
|
||||
def __init__(self, x):
|
||||
pass
|
||||
assert funcargs.getfuncargnames(A) == ["x"]
|
||||
|
||||
class TestFillFuncArgs:
|
||||
def test_fillfuncargs_exposed(self):
|
||||
# used by oejskit
|
||||
|
@ -1727,6 +1732,26 @@ class TestFuncargFactory:
|
|||
])
|
||||
|
||||
|
||||
def test_factory_setup_as_classes(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
class arg1:
|
||||
def __init__(self, request):
|
||||
self.x = 1
|
||||
arg1 = pytest.factory()(arg1)
|
||||
|
||||
class MySetup:
|
||||
def __init__(self, request, arg1):
|
||||
request.instance.arg1 = arg1
|
||||
pytest.setup()(MySetup)
|
||||
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
assert self.arg1.x == 1
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
|
||||
class TestResourceIntegrationFunctional:
|
||||
def test_parametrize_with_ids(self, testdir):
|
||||
|
|
Loading…
Reference in New Issue