Allow parameterised fixtures to give paramemter IDs
This is just like the markers etc already can do.
This commit is contained in:
parent
1b7c70eab4
commit
0c737e3de0
|
@ -1,6 +1,9 @@
|
||||||
Unreleased
|
Unreleased
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
- Allow parameterized fixtures to specify the ID of the parameters by
|
||||||
|
adding an ids argument to pytest.fixture() and pytest.yield_fixture().
|
||||||
|
|
||||||
- fix issue404 by always using the binary xml escape in the junitxml plugin
|
- fix issue404 by always using the binary xml escape in the junitxml plugin
|
||||||
|
|
||||||
2.5.0
|
2.5.0
|
||||||
|
|
|
@ -35,11 +35,13 @@ def getimfunc(func):
|
||||||
|
|
||||||
|
|
||||||
class FixtureFunctionMarker:
|
class FixtureFunctionMarker:
|
||||||
def __init__(self, scope, params, autouse=False, yieldctx=False):
|
def __init__(self, scope, params,
|
||||||
|
autouse=False, yieldctx=False, ids=None):
|
||||||
self.scope = scope
|
self.scope = scope
|
||||||
self.params = params
|
self.params = params
|
||||||
self.autouse = autouse
|
self.autouse = autouse
|
||||||
self.yieldctx = yieldctx
|
self.yieldctx = yieldctx
|
||||||
|
self.ids = ids
|
||||||
|
|
||||||
def __call__(self, function):
|
def __call__(self, function):
|
||||||
if inspect.isclass(function):
|
if inspect.isclass(function):
|
||||||
|
@ -49,7 +51,7 @@ class FixtureFunctionMarker:
|
||||||
return function
|
return function
|
||||||
|
|
||||||
|
|
||||||
def fixture(scope="function", params=None, autouse=False):
|
def fixture(scope="function", params=None, autouse=False, ids=None):
|
||||||
""" (return a) decorator to mark a fixture factory function.
|
""" (return a) decorator to mark a fixture factory function.
|
||||||
|
|
||||||
This decorator can be used (with or or without parameters) to define
|
This decorator can be used (with or or without parameters) to define
|
||||||
|
@ -71,6 +73,10 @@ def fixture(scope="function", params=None, autouse=False):
|
||||||
can see it. If False (the default) then an explicit
|
can see it. If False (the default) then an explicit
|
||||||
reference is needed to activate the fixture.
|
reference is needed to activate the fixture.
|
||||||
|
|
||||||
|
:arg ids: list of string ids each corresponding to the argvalues
|
||||||
|
so that they are part of the test id. If no ids are provided
|
||||||
|
they will be generated automatically from the argvalues.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if callable(scope) and params is None and autouse == False:
|
if callable(scope) and params is None and autouse == False:
|
||||||
# direct decoration
|
# direct decoration
|
||||||
|
@ -78,9 +84,9 @@ def fixture(scope="function", params=None, autouse=False):
|
||||||
"function", params, autouse)(scope)
|
"function", params, autouse)(scope)
|
||||||
if params is not None and not isinstance(params, (list, tuple)):
|
if params is not None and not isinstance(params, (list, tuple)):
|
||||||
params = list(params)
|
params = list(params)
|
||||||
return FixtureFunctionMarker(scope, params, autouse)
|
return FixtureFunctionMarker(scope, params, autouse, ids=ids)
|
||||||
|
|
||||||
def yield_fixture(scope="function", params=None, autouse=False):
|
def yield_fixture(scope="function", params=None, autouse=False, ids=None):
|
||||||
""" (return a) decorator to mark a yield-fixture factory function
|
""" (return a) decorator to mark a yield-fixture factory function
|
||||||
(EXPERIMENTAL).
|
(EXPERIMENTAL).
|
||||||
|
|
||||||
|
@ -94,7 +100,8 @@ def yield_fixture(scope="function", params=None, autouse=False):
|
||||||
return FixtureFunctionMarker(
|
return FixtureFunctionMarker(
|
||||||
"function", params, autouse, yieldctx=True)(scope)
|
"function", params, autouse, yieldctx=True)(scope)
|
||||||
else:
|
else:
|
||||||
return FixtureFunctionMarker(scope, params, autouse, yieldctx=True)
|
return FixtureFunctionMarker(scope, params, autouse,
|
||||||
|
yieldctx=True, ids=ids)
|
||||||
|
|
||||||
defaultfuncargprefixmarker = fixture()
|
defaultfuncargprefixmarker = fixture()
|
||||||
|
|
||||||
|
@ -1623,7 +1630,8 @@ class FixtureManager:
|
||||||
for fixturedef in faclist:
|
for fixturedef in faclist:
|
||||||
if fixturedef.params is not None:
|
if fixturedef.params is not None:
|
||||||
metafunc.parametrize(argname, fixturedef.params,
|
metafunc.parametrize(argname, fixturedef.params,
|
||||||
indirect=True, scope=fixturedef.scope)
|
indirect=True, scope=fixturedef.scope,
|
||||||
|
ids=fixturedef.ids)
|
||||||
|
|
||||||
def pytest_collection_modifyitems(self, items):
|
def pytest_collection_modifyitems(self, items):
|
||||||
# separate parametrized setups
|
# separate parametrized setups
|
||||||
|
@ -1660,7 +1668,7 @@ class FixtureManager:
|
||||||
fixturedef = FixtureDef(self, nodeid, name, obj,
|
fixturedef = FixtureDef(self, nodeid, name, obj,
|
||||||
marker.scope, marker.params,
|
marker.scope, marker.params,
|
||||||
yieldctx=marker.yieldctx,
|
yieldctx=marker.yieldctx,
|
||||||
unittest=unittest)
|
unittest=unittest, ids=marker.ids)
|
||||||
faclist = self._arg2fixturedefs.setdefault(name, [])
|
faclist = self._arg2fixturedefs.setdefault(name, [])
|
||||||
if fixturedef.has_location:
|
if fixturedef.has_location:
|
||||||
faclist.append(fixturedef)
|
faclist.append(fixturedef)
|
||||||
|
@ -1728,7 +1736,7 @@ def call_fixture_func(fixturefunc, request, kwargs, yieldctx):
|
||||||
class FixtureDef:
|
class FixtureDef:
|
||||||
""" A container for a factory definition. """
|
""" A container for a factory definition. """
|
||||||
def __init__(self, fixturemanager, baseid, argname, func, scope, params,
|
def __init__(self, fixturemanager, baseid, argname, func, scope, params,
|
||||||
yieldctx, unittest=False):
|
yieldctx, unittest=False, ids=None):
|
||||||
self._fixturemanager = fixturemanager
|
self._fixturemanager = fixturemanager
|
||||||
self.baseid = baseid or ''
|
self.baseid = baseid or ''
|
||||||
self.has_location = baseid is not None
|
self.has_location = baseid is not None
|
||||||
|
@ -1741,6 +1749,7 @@ class FixtureDef:
|
||||||
self.argnames = getfuncargnames(func, startindex=startindex)
|
self.argnames = getfuncargnames(func, startindex=startindex)
|
||||||
self.yieldctx = yieldctx
|
self.yieldctx = yieldctx
|
||||||
self.unittest = unittest
|
self.unittest = unittest
|
||||||
|
self.ids = ids
|
||||||
self._finalizer = []
|
self._finalizer = []
|
||||||
|
|
||||||
def addfinalizer(self, finalizer):
|
def addfinalizer(self, finalizer):
|
||||||
|
|
|
@ -1989,6 +1989,40 @@ class TestFixtureMarker:
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
def test_params_and_ids(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[object(), object()],
|
||||||
|
ids=['alpha', 'beta'])
|
||||||
|
def fix(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
def test_foo(fix):
|
||||||
|
assert 1
|
||||||
|
""")
|
||||||
|
res = testdir.runpytest('-v')
|
||||||
|
res.stdout.fnmatch_lines([
|
||||||
|
'*test_foo*alpha*',
|
||||||
|
'*test_foo*beta*'])
|
||||||
|
|
||||||
|
def test_params_and_ids_yieldfixture(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.yield_fixture(params=[object(), object()],
|
||||||
|
ids=['alpha', 'beta'])
|
||||||
|
def fix(request):
|
||||||
|
yield request.param
|
||||||
|
|
||||||
|
def test_foo(fix):
|
||||||
|
assert 1
|
||||||
|
""")
|
||||||
|
res = testdir.runpytest('-v')
|
||||||
|
res.stdout.fnmatch_lines([
|
||||||
|
'*test_foo*alpha*',
|
||||||
|
'*test_foo*beta*'])
|
||||||
|
|
||||||
|
|
||||||
class TestRequestScopeAccess:
|
class TestRequestScopeAccess:
|
||||||
pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[
|
pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[
|
||||||
|
|
Loading…
Reference in New Issue