Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pytest does not support indirect parameters for overriden fixtures #2043

Open
acatton opened this issue Nov 4, 2016 · 2 comments
Open

Pytest does not support indirect parameters for overriden fixtures #2043

acatton opened this issue Nov 4, 2016 · 2 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly type: refactoring internal improvements to the code

Comments

@acatton
Copy link

acatton commented Nov 4, 2016

Here's my minimum test case:

$ pip freeze
py==1.4.31
pytest==3.0.3

Here's my test case:

import pytest


@pytest.fixture(params=[3])
def a(request):
    return 'a' * request.param


@pytest.fixture(params=[2])
def b(request):
    return 'b' * request.param


@pytest.fixture
def ab(a, b):
    return ':'.join([a, b])


class OverridenMixin(object):
    @pytest.fixture
    def ab(self, ab):
        """Just override 'ab' in this class"""
        return '--{}--'.format(ab)


class TestNormal(object):
    def test_ab(self, ab):
        assert ab == 'aaa:bb'

    @pytest.mark.parametrize('a,b', [(1, 1)], indirect=True)
    def test_ab_with_different_parameters(self, ab):
        assert ab == 'a:b'


class TestOverriden(OverridenMixin):
    def test_ab(self, ab):
        assert ab == '--aaa:bb--'

    @pytest.mark.parametrize('a,b', [(1, 1)], indirect=True)
    def test_ab_with_different_parameters(self, ab):
        assert ab == '--a:b--'

I get the error:

=============================================================================================== test session starts ===============================================================================================
platform linux2 -- Python 2.7.12, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- /tmp/tmp.5aQF8ckzpV/.tmp.5aQF8ckzpV/bin/python
cachedir: .cache
rootdir: /tmp/tmp.5aQF8ckzpV, inifile: 
collected 2 items / 1 errors 

===================================================================================================== ERRORS ======================================================================================================
______________________________________________________________________________________________ ERROR collecting a.py ______________________________________________________________________________________________
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/runner.py:163: in __init__
    self.result = func()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/main.py:460: in _memocollect
    return self._memoizedcall('_collected', lambda: list(self.collect()))
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/main.py:331: in _memoizedcall
    res = function()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/main.py:460: in <lambda>
    return self._memoizedcall('_collected', lambda: list(self.collect()))
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:521: in collect
    return super(Instance, self).collect()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:318: in collect
    res = self.makeitem(name, obj)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:330: in makeitem
    collector=self, name=name, obj=obj)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:745: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:339: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:334: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:613: in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:250: in _wrapped_call
    wrap_controller.send(call_outcome)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:192: in pytest_pycollect_makeitem
    res = list(collector._genfunctions(name, obj))
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:350: in _genfunctions
    self.ihook.pytest_generate_tests(metafunc=metafunc)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:745: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:339: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:334: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:614: in execute
    res = hook_impl.function(*args)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:105: in pytest_generate_tests
    metafunc.parametrize(*marker.args, **marker.kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:813: in parametrize
    self.function, name, arg))
E   ValueError: <function test_ab_with_different_parameters at 0x7fc6ecdb4de8> uses no fixture 'a'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================================= 1 error in 0.41 seconds =============================================================================================

More interesting, if I commented out the last test (TestOverriden::test_ab_with_different_parameters) I get:

===================================================================================================== ERRORS ======================================================================================================
_____________________________________________________________________________________ ERROR at setup of TestOverriden.test_ab _____________________________________________________________________________________

self = <CallInfo when='setup' exception: The requested fixture has no parameter defined for the current test.

Requested fixture 'a' defined in:
a.py:5

Requested here:
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:529>
func = <function <lambda> at 0x7f726a6a6e60>, when = 'setup'

    def __init__(self, func, when):
        #: context of invocation: one of "setup", "call",
        #: "teardown", "memocollect"
        self.when = when
        self.start = time()
        try:
>           self.result = func()

.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/runner.py:163: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/runner.py:151: in <lambda>
    return CallInfo(lambda: ihook(item=item, **kwds), when=when)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:745: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:339: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:334: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:613: in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:254: in _wrapped_call
    return call_outcome.get_result()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:280: in get_result
    _reraise(*ex)  # noqa
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:265: in __init__
    self.result = func()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py:614: in execute
    res = hook_impl.function(*args)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/runner.py:100: in pytest_runtest_setup
    item.session._setupstate.prepare(item)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/runner.py:453: in prepare
    col.setup()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/python.py:1560: in setup
    fixtures.fillfixtures(self)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:252: in fillfixtures
    request._fillfixtures()
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:397: in _fillfixtures
    item.funcargs[argname] = self.getfixturevalue(argname)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:439: in getfixturevalue
    return self._get_active_fixturedef(argname).cached_result[0]
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:464: in _get_active_fixturedef
    result = self._getfixturevalue(fixturedef)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:529: in _getfixturevalue
    val = fixturedef.execute(request=subrequest)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:766: in execute
    fixturedef = request._get_active_fixturedef(argname)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:464: in _get_active_fixturedef
    result = self._getfixturevalue(fixturedef)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:529: in _getfixturevalue
    val = fixturedef.execute(request=subrequest)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:766: in execute
    fixturedef = request._get_active_fixturedef(argname)
.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:464: in _get_active_fixturedef
    result = self._getfixturevalue(fixturedef)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <SubRequest 'ab' for <Function 'test_ab'>>, fixturedef = <FixtureDef name='a' scope='function' baseid='a.py' >

    def _getfixturevalue(self, fixturedef):
        # prepare a subrequest object before calling fixture function
        # (latter managed by fixturedef)
        argname = fixturedef.argname
        funcitem = self._pyfuncitem
        scope = fixturedef.scope
        try:
            param = funcitem.callspec.getparam(argname)
        except (AttributeError, ValueError):
            param = NOTSET
            param_index = 0
            if fixturedef.params is not None:
                frame = inspect.stack()[3]
                frameinfo = inspect.getframeinfo(frame[0])
                source_path = frameinfo.filename
                source_lineno = frameinfo.lineno
                source_path = py.path.local(source_path)
                if source_path.relto(funcitem.config.rootdir):
                    source_path = source_path.relto(funcitem.config.rootdir)
                msg = (
                    "The requested fixture has no parameter defined for the "
                    "current test.\n\nRequested fixture '{0}' defined in:\n{1}"
                    "\n\nRequested here:\n{2}:{3}".format(
                        fixturedef.argname,
                        getlocation(fixturedef.func, funcitem.config.rootdir),
                        source_path,
                        source_lineno,
                    )
                )
>               pytest.fail(msg)
E               Failed: The requested fixture has no parameter defined for the current test.
E               
E               Requested fixture 'a' defined in:
E               a.py:5
E               
E               Requested here:
E               .tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:529

.tmp.5aQF8ckzpV/lib/python2.7/site-packages/_pytest/fixtures.py:509: Failed
======================================================================================== 2 passed, 1 error in 0.39 seconds ========================================================================================
@jmoldow
Copy link
Contributor

jmoldow commented Dec 15, 2016

Your second error sounds similar to #1953 , and I'm guessing that all three errors are caused by the same thing.

@RonnyPfannschmidt
Copy link
Member

the fixture mechanism currently is completely unable to map a topology of overrides

@hpk42 i presume this one is next to impossible to do without major refactoring?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: refactoring internal improvements to the code
Projects
None yet
Development

No branches or pull requests

4 participants