Skip to content

Commit fc400b2

Browse files
committed
allow staticmethods to be detected as test functions
Allow a class method decorated `@staticmethod` to be collected as a test function (if it meets the usual criteria). This feature will not work in Python 2.6 -- static methods will still be ignored there.
1 parent 9b51fc6 commit fc400b2

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ Michael Droettboom
118118
Michael Seifert
119119
Michal Wajszczuk
120120
Mike Lundy
121+
Nathaniel Waisbrot
121122
Ned Batchelder
122123
Neven Mundar
123124
Nicolas Delaby

_pytest/python.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,16 @@ def classnamefilter(self, name):
271271
return self._matches_prefix_or_glob_option('python_classes', name)
272272

273273
def istestfunction(self, obj, name):
274-
return (
275-
(self.funcnamefilter(name) or self.isnosetest(obj)) and
276-
safe_getattr(obj, "__call__", False) and fixtures.getfixturemarker(obj) is None
277-
)
274+
if self.funcnamefilter(name) or self.isnosetest(obj):
275+
if isinstance(obj, staticmethod):
276+
# static methods need to be unwrapped
277+
obj = safe_getattr(obj, '__func__', False)
278+
if obj is False:
279+
# Python 2.6 wraps in a different way that we won't try to handle
280+
self.warn(code="C2", message="cannot collect static method %r because it is not a function (always the case in Python 2.6)" % name)
281+
return (
282+
safe_getattr(obj, "__call__", False) and fixtures.getfixturemarker(obj) is None
283+
)
278284

279285
def istestclass(self, obj, name):
280286
return self.classnamefilter(name) or self.isnosetest(obj)

changelog/2528.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow class methods decorated as ``@staticmethod`` to be candidates for collection as a test function. (Only for Python 2.7 and above. Python 2.6 will still ignore static methods.)

testing/python/collect.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ class test(object):
143143
"*collected 0*",
144144
])
145145

146+
def test_static_method(self, testdir):
147+
testdir.getmodulecol("""
148+
class Test(object):
149+
@staticmethod
150+
def test_something():
151+
pass
152+
""")
153+
result = testdir.runpytest()
154+
if sys.version_info < (2,7):
155+
# in 2.6, the code to handle static methods doesn't work
156+
result.stdout.fnmatch_lines(["*collected 0*"])
157+
else:
158+
result.stdout.fnmatch_lines([
159+
"*collected 1*",
160+
])
161+
146162
def test_setup_teardown_class_as_classmethod(self, testdir):
147163
testdir.makepyfile(test_mod1="""
148164
class TestClassMethod(object):

0 commit comments

Comments
 (0)