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
|
||||
Simon Gomizelj
|
||||
Stefano Taschini
|
||||
Stefan Farmbauer
|
||||
Thomas Grainger
|
||||
Tom Viner
|
||||
Trevor Bekolay
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Text documents without any doctests no longer appear as "skipped".
|
||||
Thanks `@graingert`_ for reporting and providing a full PR (`#1580`_).
|
||||
|
||||
* Fix internal error issue when ``method`` argument is missing for
|
||||
* Fix internal error issue when ``method`` argument is missing for
|
||||
``teardown_method()``. Fixes (`#1605`_).
|
||||
|
||||
* Fix exception visualization in case the current working directory (CWD) gets
|
||||
|
@ -17,14 +17,21 @@
|
|||
is specified on the command line together with the ``--pyargs``
|
||||
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
|
||||
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
|
||||
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
|
||||
.. _#460: https://github.com/pytest-dev/pytest/pull/460
|
||||
|
||||
.. _@graingert: https://github.com/graingert
|
||||
.. _@taschini: https://github.com/taschini
|
||||
.. _@nikratio: https://github.com/nikratio
|
||||
.. _@RedBeardCode: https://github.com/RedBeardCode
|
||||
|
||||
|
||||
2.9.2
|
||||
|
|
|
@ -1651,6 +1651,25 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
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)
|
||||
else:
|
||||
# indices might not be set if old-style metafunc.addcall() was used
|
||||
param_index = funcitem.callspec.indices.get(argname, 0)
|
||||
|
|
|
@ -2723,3 +2723,108 @@ class TestContextManagerFixtureFuncs:
|
|||
*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