Merge pull request #1444 from novas0x2a/fixture-custom-name

Allow custom fixture names for fixtures
This commit is contained in:
Ronny Pfannschmidt 2016-03-14 14:08:02 +01:00
commit 0cacdef6c5
4 changed files with 33 additions and 5 deletions

View File

@ -63,6 +63,7 @@ Matt Williams
Michael Aquilina
Michael Birtwell
Michael Droettboom
Mike Lundy
Nicolas Delaby
Pieter Mulder
Piotr Banaszkiewicz

View File

@ -7,7 +7,11 @@
namespace in which your doctests run.
Thanks `@milliams`_ for the complete PR (`#1428`_).
*
* New ``name`` argument to ``pytest.fixture`` mark, which allows a custom name
for a fixture (to solve the funcarg-shadowing-fixture problem).
Thanks `@novas0x2a`_ for the complete PR (`#1444`_).
*
*
@ -21,8 +25,10 @@
*
.. _@milliams: https://github.com/milliams
.. _@novas0x2a: https://github.com/novas0x2a
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428
.. _#1444: https://github.com/pytest-dev/pytest/pull/1444
2.9.1.dev1

View File

@ -114,12 +114,13 @@ def safe_getattr(object, name, default):
class FixtureFunctionMarker:
def __init__(self, scope, params,
autouse=False, yieldctx=False, ids=None):
autouse=False, yieldctx=False, ids=None, name=None):
self.scope = scope
self.params = params
self.autouse = autouse
self.yieldctx = yieldctx
self.ids = ids
self.name = name
def __call__(self, function):
if isclass(function):
@ -129,7 +130,7 @@ class FixtureFunctionMarker:
return function
def fixture(scope="function", params=None, autouse=False, ids=None):
def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
""" (return a) decorator to mark a fixture factory function.
This decorator can be used (with or or without parameters) to define
@ -155,14 +156,21 @@ def fixture(scope="function", params=None, autouse=False, ids=None):
so that they are part of the test id. If no ids are provided
they will be generated automatically from the params.
:arg name: the name of the fixture. This defaults to the name of the
decorated function. If a fixture is used in the same module in
which it is defined, the function name of the fixture will be
shadowed by the function arg that requests the fixture; one way
to resolve this is to name the decorated function
``fixture_<fixturename>`` and then use
``@pytest.fixture(name='<fixturename>')``.
"""
if callable(scope) and params is None and autouse == False:
# direct decoration
return FixtureFunctionMarker(
"function", params, autouse)(scope)
"function", params, autouse, name=name)(scope)
if params is not None and not isinstance(params, (list, tuple)):
params = list(params)
return FixtureFunctionMarker(scope, params, autouse, ids=ids)
return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
def yield_fixture(scope="function", params=None, autouse=False, ids=None):
""" (return a) decorator to mark a yield-fixture factory function
@ -1989,6 +1997,8 @@ class FixtureManager:
# fixture attribute
continue
else:
if marker.name:
name = marker.name
assert not name.startswith(self._argprefix)
fixturedef = FixtureDef(self, nodeid, name, obj,
marker.scope, marker.params,

View File

@ -2691,3 +2691,14 @@ class TestContextManagerFixtureFuncs:
*def arg1*
""")
def test_custom_name(self, testdir):
testdir.makepyfile("""
import pytest
@pytest.fixture(name='meow')
def arg1():
return 'mew'
def test_1(meow):
print(meow)
""")
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines("*mew*")