Merge pull request #2700 from nicoddemus/staticmethods-fixtures

Allow tests declared as @staticmethod to use fixtures
This commit is contained in:
Ronny Pfannschmidt 2017-09-06 08:24:00 +02:00 committed by GitHub
commit ad36407747
5 changed files with 29 additions and 8 deletions

View File

@ -83,7 +83,15 @@ def num_mock_patch_args(function):
return len(patchings) return len(patchings)
def getfuncargnames(function, startindex=None): def getfuncargnames(function, startindex=None, cls=None):
"""
@RonnyPfannschmidt: This function should be refactored when we revisit fixtures. The
fixture mechanism should ask the node for the fixture names, and not try to obtain
directly from the function object well after collection has occurred.
"""
if startindex is None and cls is not None:
is_staticmethod = isinstance(cls.__dict__.get(function.__name__, None), staticmethod)
startindex = 0 if is_staticmethod else 1
# XXX merge with main.py's varnames # XXX merge with main.py's varnames
# assert not isclass(function) # assert not isclass(function)
realfunction = function realfunction = function

View File

@ -957,11 +957,7 @@ class FixtureManager:
def getfixtureinfo(self, node, func, cls, funcargs=True): def getfixtureinfo(self, node, func, cls, funcargs=True):
if funcargs and not hasattr(node, "nofuncargs"): if funcargs and not hasattr(node, "nofuncargs"):
if cls is not None: argnames = getfuncargnames(func, cls=cls)
startindex = 1
else:
startindex = None
argnames = getfuncargnames(func, startindex)
else: else:
argnames = () argnames = ()
usefixtures = getattr(func, "usefixtures", None) usefixtures = getattr(func, "usefixtures", None)

1
changelog/2699.bugfix Normal file
View File

@ -0,0 +1 @@
Allow tests declared as ``@staticmethod`` to use fixtures.

View File

@ -147,11 +147,21 @@ class TestClass(object):
]) ])
def test_static_method(self, testdir): def test_static_method(self, testdir):
"""Support for collecting staticmethod tests (#2528, #2699)"""
testdir.getmodulecol(""" testdir.getmodulecol("""
import pytest
class Test(object): class Test(object):
@staticmethod @staticmethod
def test_something(): def test_something():
pass pass
@pytest.fixture
def fix(self):
return 1
@staticmethod
def test_fix(fix):
assert fix == 1
""") """)
result = testdir.runpytest() result = testdir.runpytest()
if sys.version_info < (2, 7): if sys.version_info < (2, 7):
@ -162,8 +172,8 @@ class TestClass(object):
]) ])
else: else:
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"*collected 1 item*", "*collected 2 items*",
"*1 passed in*", "*2 passed in*",
]) ])
def test_setup_teardown_class_as_classmethod(self, testdir): def test_setup_teardown_class_as_classmethod(self, testdir):

View File

@ -29,10 +29,16 @@ def test_getfuncargnames():
def f(self, arg1, arg2="hello"): def f(self, arg1, arg2="hello"):
pass pass
@staticmethod
def static(arg1, arg2):
pass
assert fixtures.getfuncargnames(A().f) == ('arg1',) assert fixtures.getfuncargnames(A().f) == ('arg1',)
if sys.version_info < (3, 0): if sys.version_info < (3, 0):
assert fixtures.getfuncargnames(A.f) == ('arg1',) assert fixtures.getfuncargnames(A.f) == ('arg1',)
assert fixtures.getfuncargnames(A.static, cls=A) == ('arg1', 'arg2')
class TestFillFixtures(object): class TestFillFixtures(object):
def test_fillfuncargs_exposed(self): def test_fillfuncargs_exposed(self):