Skip to content

Commit dc5f9e6

Browse files
blueyedtimb07
authored andcommitted
unittest: help with setUpClass not being a classmethod (pytest-dev#544)
1 parent 135479e commit dc5f9e6

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

pytest_django/plugin.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
CONFIGURATION_ENV = 'DJANGO_CONFIGURATION'
4343
INVALID_TEMPLATE_VARS_ENV = 'FAIL_INVALID_TEMPLATE_VARS'
4444

45+
PY2 = sys.version_info[0] == 2
46+
4547

4648
# ############### pytest hooks ################
4749

@@ -263,7 +265,7 @@ def pytest_configure():
263265
_setup_django()
264266

265267

266-
def _method_is_defined_at_leaf(cls, method_name):
268+
def _classmethod_is_defined_at_leaf(cls, method_name):
267269
super_method = None
268270

269271
for base_cls in cls.__bases__:
@@ -273,7 +275,15 @@ def _method_is_defined_at_leaf(cls, method_name):
273275
assert super_method is not None, (
274276
'%s could not be found in base class' % method_name)
275277

276-
return getattr(cls, method_name).__func__ is not super_method.__func__
278+
method = getattr(cls, method_name)
279+
280+
try:
281+
f = method.__func__
282+
except AttributeError:
283+
pytest.fail('%s.%s should be a classmethod' % (cls, method_name))
284+
if PY2 and not (inspect.ismethod(method) and method.__self__ is cls):
285+
pytest.fail('%s.%s should be a classmethod' % (cls, method_name))
286+
return f is not super_method.__func__
277287

278288

279289
_disabled_classmethods = {}
@@ -285,9 +295,9 @@ def _disable_class_methods(cls):
285295

286296
_disabled_classmethods[cls] = (
287297
cls.setUpClass,
288-
_method_is_defined_at_leaf(cls, 'setUpClass'),
298+
_classmethod_is_defined_at_leaf(cls, 'setUpClass'),
289299
cls.tearDownClass,
290-
_method_is_defined_at_leaf(cls, 'tearDownClass'),
300+
_classmethod_is_defined_at_leaf(cls, 'tearDownClass'),
291301
)
292302

293303
cls.setUpClass = types.MethodType(lambda cls: None, cls)

tests/test_unittest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,25 @@ def test_pass(self):
122122
])
123123
assert result.ret == 0
124124

125+
def test_setUpClass_not_being_a_classmethod(self, django_testdir):
126+
django_testdir.create_test_module('''
127+
from django.test import TestCase
128+
129+
class TestFoo(TestCase):
130+
def setUpClass(self):
131+
pass
132+
133+
def test_pass(self):
134+
pass
135+
''')
136+
137+
result = django_testdir.runpytest_subprocess('-v', '-s')
138+
result.stdout.fnmatch_lines([
139+
"* ERROR at setup of TestFoo.test_pass *",
140+
"E *Failed: <class 'tpkg.test_the_test.TestFoo'>.setUpClass should be a classmethod", # noqa:E501
141+
])
142+
assert result.ret == 1
143+
125144
def test_multi_inheritance_setUpClass(self, django_testdir):
126145
django_testdir.create_test_module('''
127146
from django.test import TestCase

0 commit comments

Comments
 (0)