Request #714: Apply indirect=True on particular argnames
This commit is contained in:
parent
ae28e4ba0f
commit
2fc7aede0b
|
@ -761,11 +761,12 @@ class CallSpec2(object):
|
|||
def id(self):
|
||||
return "-".join(map(str, filter(None, self._idlist)))
|
||||
|
||||
def setmulti(self, valtype, argnames, valset, id, keywords, scopenum,
|
||||
def setmulti(self, valtypes, argnames, valset, id, keywords, scopenum,
|
||||
param_index):
|
||||
for arg,val in zip(argnames, valset):
|
||||
self._checkargnotcontained(arg)
|
||||
getattr(self, valtype)[arg] = val
|
||||
valtype_for_arg = valtypes[arg]
|
||||
getattr(self, valtype_for_arg)[arg] = val
|
||||
self.indices[arg] = param_index
|
||||
self._arg2scopenum[arg] = scopenum
|
||||
if val is _notexists:
|
||||
|
@ -844,7 +845,9 @@ class Metafunc(FuncargnamesCompatAttr):
|
|||
where each tuple-element specifies a value for its respective
|
||||
argname.
|
||||
|
||||
:arg indirect: if True each argvalue corresponding to an argname will
|
||||
:arg indirect: The list of argnames or boolean. A list of arguments'
|
||||
names (subset of argnames). If True the list contains all names from
|
||||
the argnames. Each argvalue corresponding to an argname in this list will
|
||||
be passed as request.param to its respective argname fixture
|
||||
function so that it can perform more expensive setups during the
|
||||
setup phase of a test rather than at collection time.
|
||||
|
@ -889,13 +892,22 @@ class Metafunc(FuncargnamesCompatAttr):
|
|||
if scope is None:
|
||||
scope = "function"
|
||||
scopenum = scopes.index(scope)
|
||||
valtypes = {arg: "funcargs" for arg in argnames}
|
||||
if not indirect:
|
||||
#XXX should we also check for the opposite case?
|
||||
for arg in argnames:
|
||||
if arg not in self.fixturenames:
|
||||
raise ValueError("%r uses no fixture %r" %(
|
||||
self.function, arg))
|
||||
valtype = indirect and "params" or "funcargs"
|
||||
else:
|
||||
if not isinstance(indirect, (tuple, list)):
|
||||
valtypes = {arg: "params" for arg in argnames}
|
||||
else:
|
||||
for arg in indirect:
|
||||
if arg not in argnames:
|
||||
raise ValueError("indirect: fixture %r doesn't exist" %(
|
||||
arg))
|
||||
valtypes[arg] = "params"
|
||||
idfn = None
|
||||
if callable(ids):
|
||||
idfn = ids
|
||||
|
@ -910,7 +922,7 @@ class Metafunc(FuncargnamesCompatAttr):
|
|||
for param_index, valset in enumerate(argvalues):
|
||||
assert len(valset) == len(argnames)
|
||||
newcallspec = callspec.copy(self)
|
||||
newcallspec.setmulti(valtype, argnames, valset, ids[param_index],
|
||||
newcallspec.setmulti(valtypes, argnames, valset, ids[param_index],
|
||||
newkeywords.get(param_index, {}), scopenum,
|
||||
param_index)
|
||||
newcalls.append(newcallspec)
|
||||
|
|
|
@ -220,6 +220,46 @@ class TestMetafunc:
|
|||
assert metafunc._calls[0].params == dict(x=1,y=2, unnamed=1)
|
||||
assert metafunc._calls[1].params == dict(x=1,y=3, unnamed=1)
|
||||
|
||||
def test_parametrize_indirect_list(self):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
metafunc.parametrize('x, y', [('a', 'b')], indirect=['x'])
|
||||
assert metafunc._calls[0].funcargs == dict(y='b')
|
||||
assert metafunc._calls[0].params == dict(x='a')
|
||||
|
||||
def test_parametrize_indirect_list_all(self):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
metafunc.parametrize('x, y', [('a', 'b')], indirect=['x', 'y'])
|
||||
assert metafunc._calls[0].funcargs == {}
|
||||
assert metafunc._calls[0].params == dict(x='a', y='b')
|
||||
|
||||
def test_parametrize_indirect_list_empty(self):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
metafunc.parametrize('x, y', [('a', 'b')], indirect=[])
|
||||
assert metafunc._calls[0].funcargs == dict(x='a', y='b')
|
||||
assert metafunc._calls[0].params == {}
|
||||
|
||||
def test_parametrize_indirect_list_functional(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
def pytest_generate_tests(metafunc):
|
||||
metafunc.parametrize('x, y', [('a', 'b')], indirect=['x'])
|
||||
def pytest_funcarg__x(request):
|
||||
return request.param * 3
|
||||
def pytest_funcarg__y(request):
|
||||
return request.param * 2
|
||||
|
||||
def test_simple(x,y):
|
||||
assert len(x) == 3
|
||||
assert len(y) == 1
|
||||
""")
|
||||
result = testdir.runpytest("-v")
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_simple*a-b*",
|
||||
"*1 passed*",
|
||||
])
|
||||
|
||||
def test_addcalls_and_parametrize_indirect(self):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
|
|
Loading…
Reference in New Issue