Explain a bad scope value to the user

This commit is contained in:
Tyler Goodlet 2016-09-06 14:16:25 -04:00
parent 7660a19d0a
commit 6db2f315fa
6 changed files with 55 additions and 4 deletions

View File

@ -127,6 +127,7 @@ Ted Xiao
Thomas Grainger
Tom Viner
Trevor Bekolay
Tyler Goodlet
Vasily Kuznetsov
Wouter van Ackooy
Xuecong Liao

View File

@ -16,18 +16,21 @@
in Python 3 (`#1944`_).
Thanks `@axil`_ for the PR.
*
* Explain a bad scope value passed to ``@fixture`` declarations or
a ``MetaFunc.parametrize()`` call. Thanks `@tgoodlet`_ for the PR.
.. _@philpep: https://github.com/philpep
.. _@raquel-ucl: https://github.com/raquel-ucl
.. _@axil: https://github.com/axil
.. _@tgoodlet: https://github.com/tgoodlet
.. _#1905: https://github.com/pytest-dev/pytest/issues/1905
.. _#1934: https://github.com/pytest-dev/pytest/issues/1934
.. _#1944: https://github.com/pytest-dev/pytest/issues/1944
3.0.2
=====

View File

@ -599,12 +599,29 @@ class ScopeMismatchError(Exception):
which has a lower scope (e.g. a Session one calls a function one)
"""
scopes = "session module class function".split()
scopenum_function = scopes.index("function")
def scopemismatch(currentscope, newscope):
return scopes.index(newscope) > scopes.index(currentscope)
def scope2index(scope, descr, where=None):
"""Look up the index of ``scope`` and raise a descriptive value error
if not defined.
"""
try:
return scopes.index(scope)
except ValueError:
raise ValueError(
"{0} {1}has an unsupported scope value '{2}'".format(
descr, 'from {0} '.format(where) if where else '',
scope)
)
class FixtureLookupError(LookupError):
""" could not return a requested Fixture (missing or invalid). """
def __init__(self, argname, request, msg=None):
@ -703,6 +720,7 @@ def call_fixture_func(fixturefunc, request, kwargs):
res = fixturefunc(**kwargs)
return res
class FixtureDef:
""" A container for a factory definition. """
def __init__(self, fixturemanager, baseid, argname, func, scope, params,
@ -713,7 +731,11 @@ class FixtureDef:
self.func = func
self.argname = argname
self.scope = scope
self.scopenum = scopes.index(scope or "function")
self.scopenum = scope2index(
scope or "function",
descr='fixture {0}'.format(func.__name__),
where=baseid
)
self.params = params
startindex = unittest and 1 or None
self.argnames = getfuncargnames(func, startindex=startindex)

View File

@ -770,7 +770,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
It will also override any fixture-function defined scope, allowing
to set a dynamic scope using test context or configuration.
"""
from _pytest.fixtures import scopes
from _pytest.fixtures import scope2index
from _pytest.mark import extract_argvalue
from py.io import saferepr
@ -799,7 +799,8 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
if scope is None:
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
scopenum = scopes.index(scope)
scopenum = scope2index(
scope, descr='call to {0}'.format(self.parametrize))
valtypes = {}
for arg in argnames:
if arg not in self.fixturenames:

View File

@ -1063,6 +1063,22 @@ class TestFixtureUsages:
"*1 error*"
])
def test_invalid_scope(self, testdir):
testdir.makepyfile("""
import pytest
@pytest.fixture(scope="functions")
def badscope():
pass
def test_nothing(badscope):
pass
""")
result = testdir.runpytest_inprocess()
result.stdout.fnmatch_lines(
("*ValueError: fixture badscope from test_invalid_scope.py has an unsupported"
" scope value 'functions'")
)
def test_funcarg_parametrized_and_used_twice(self, testdir):
testdir.makepyfile("""
import pytest

View File

@ -96,6 +96,14 @@ class TestMetafunc:
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
def test_parametrize_bad_scope(self, testdir):
def func(x): pass
metafunc = self.Metafunc(func)
try:
metafunc.parametrize("x", [1], scope='doggy')
except ValueError as ve:
assert "has an unsupported scope value 'doggy'" in str(ve)
def test_parametrize_and_id(self):
def func(x, y): pass
metafunc = self.Metafunc(func)