Merge pull request #1620 from tomviner/issue460/parameterized-subrequest
Issue 460: Fail on getfuncargvalue(<fixture with params>)
This commit is contained in:
commit
c3ee1c17bc
1
AUTHORS
1
AUTHORS
|
@ -89,6 +89,7 @@ Ryan Wooden
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
Simon Gomizelj
|
Simon Gomizelj
|
||||||
Stefano Taschini
|
Stefano Taschini
|
||||||
|
Stefan Farmbauer
|
||||||
Thomas Grainger
|
Thomas Grainger
|
||||||
Tom Viner
|
Tom Viner
|
||||||
Trevor Bekolay
|
Trevor Bekolay
|
||||||
|
|
|
@ -17,14 +17,21 @@
|
||||||
is specified on the command line together with the ``--pyargs``
|
is specified on the command line together with the ``--pyargs``
|
||||||
option. Thanks to `@taschini`_ for the PR (`#1597`_).
|
option. Thanks to `@taschini`_ for the PR (`#1597`_).
|
||||||
|
|
||||||
*
|
* Raise helpful failure message, when requesting parametrized fixture at runtime,
|
||||||
|
e.g. with ``request.getfuncargvalue``. BACKWARD INCOMPAT: Previously these params
|
||||||
|
were simply never defined. So a fixture decorated like ``@pytest.fixture(params=[0, 1, 2])``
|
||||||
|
only ran once. Now a failure is raised. Fixes (`#460`_). Thanks to
|
||||||
|
`@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for PR.
|
||||||
|
|
||||||
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580
|
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580
|
||||||
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
|
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
|
||||||
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
|
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
|
||||||
|
.. _#460: https://github.com/pytest-dev/pytest/pull/460
|
||||||
|
|
||||||
.. _@graingert: https://github.com/graingert
|
.. _@graingert: https://github.com/graingert
|
||||||
.. _@taschini: https://github.com/taschini
|
.. _@taschini: https://github.com/taschini
|
||||||
|
.. _@nikratio: https://github.com/nikratio
|
||||||
|
.. _@RedBeardCode: https://github.com/RedBeardCode
|
||||||
|
|
||||||
|
|
||||||
2.9.2
|
2.9.2
|
||||||
|
|
|
@ -1651,6 +1651,25 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
except (AttributeError, ValueError):
|
except (AttributeError, ValueError):
|
||||||
param = NOTSET
|
param = NOTSET
|
||||||
param_index = 0
|
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)
|
||||||
else:
|
else:
|
||||||
# indices might not be set if old-style metafunc.addcall() was used
|
# indices might not be set if old-style metafunc.addcall() was used
|
||||||
param_index = funcitem.callspec.indices.get(argname, 0)
|
param_index = funcitem.callspec.indices.get(argname, 0)
|
||||||
|
|
|
@ -2723,3 +2723,108 @@ class TestContextManagerFixtureFuncs:
|
||||||
*def arg1*
|
*def arg1*
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
class TestParameterizedSubRequest:
|
||||||
|
def test_call_from_fixture(self, testdir):
|
||||||
|
testfile = testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[0, 1, 2])
|
||||||
|
def fix_with_param(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def get_named_fixture(request):
|
||||||
|
return request.getfuncargvalue('fix_with_param')
|
||||||
|
|
||||||
|
def test_foo(request, get_named_fixture):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines("""
|
||||||
|
E*Failed: The requested fixture has no parameter defined for the current test.
|
||||||
|
E*
|
||||||
|
E*Requested fixture 'fix_with_param' defined in:
|
||||||
|
E*{0}:4
|
||||||
|
E*Requested here:
|
||||||
|
E*{1}:9
|
||||||
|
*1 error*
|
||||||
|
""".format(testfile.basename, testfile.basename))
|
||||||
|
|
||||||
|
def test_call_from_test(self, testdir):
|
||||||
|
testfile = testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[0, 1, 2])
|
||||||
|
def fix_with_param(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
def test_foo(request):
|
||||||
|
request.getfuncargvalue('fix_with_param')
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines("""
|
||||||
|
E*Failed: The requested fixture has no parameter defined for the current test.
|
||||||
|
E*
|
||||||
|
E*Requested fixture 'fix_with_param' defined in:
|
||||||
|
E*{0}:4
|
||||||
|
E*Requested here:
|
||||||
|
E*{1}:8
|
||||||
|
*1 failed*
|
||||||
|
""".format(testfile.basename, testfile.basename))
|
||||||
|
|
||||||
|
def test_external_fixture(self, testdir):
|
||||||
|
conffile = testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[0, 1, 2])
|
||||||
|
def fix_with_param(request):
|
||||||
|
return request.param
|
||||||
|
""")
|
||||||
|
|
||||||
|
testfile = testdir.makepyfile("""
|
||||||
|
def test_foo(request):
|
||||||
|
request.getfuncargvalue('fix_with_param')
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines("""
|
||||||
|
E*Failed: The requested fixture has no parameter defined for the current test.
|
||||||
|
E*
|
||||||
|
E*Requested fixture 'fix_with_param' defined in:
|
||||||
|
E*{0}:4
|
||||||
|
E*Requested here:
|
||||||
|
E*{1}:2
|
||||||
|
*1 failed*
|
||||||
|
""".format(conffile.basename, testfile.basename))
|
||||||
|
|
||||||
|
def test_non_relative_path(self, testdir):
|
||||||
|
tests_dir = testdir.mkdir('tests')
|
||||||
|
fixdir = testdir.mkdir('fixtures')
|
||||||
|
fixfile = fixdir.join("fix.py")
|
||||||
|
fixfile.write(_pytest._code.Source("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[0, 1, 2])
|
||||||
|
def fix_with_param(request):
|
||||||
|
return request.param
|
||||||
|
"""))
|
||||||
|
|
||||||
|
testfile = tests_dir.join("test_foos.py")
|
||||||
|
testfile.write(_pytest._code.Source("""
|
||||||
|
from fix import fix_with_param
|
||||||
|
|
||||||
|
def test_foo(request):
|
||||||
|
request.getfuncargvalue('fix_with_param')
|
||||||
|
"""))
|
||||||
|
|
||||||
|
tests_dir.chdir()
|
||||||
|
testdir.syspathinsert(fixdir)
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines("""
|
||||||
|
E*Failed: The requested fixture has no parameter defined for the current test.
|
||||||
|
E*
|
||||||
|
E*Requested fixture 'fix_with_param' defined in:
|
||||||
|
E*{0}:5
|
||||||
|
E*Requested here:
|
||||||
|
E*{1}:5
|
||||||
|
*1 failed*
|
||||||
|
""".format(fixfile.strpath, testfile.basename))
|
||||||
|
|
Loading…
Reference in New Issue