Allow tests declared as @staticmethod to use fixtures

Fix #2699
This commit is contained in:
Bruno Oliveira 2017-08-17 20:37:51 -03:00
parent 5c0c1977e3
commit a993add783
5 changed files with 24 additions and 8 deletions

View File

@ -82,7 +82,10 @@ def num_mock_patch_args(function):
return len(patchings) return len(patchings)
def getfuncargnames(function, startindex=None): def getfuncargnames(function, startindex=None, cls=None):
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):