Skip to content

Commit 0fc5220

Browse files
author
Martijn van Oosterhout
committed
Fix classmethod test.
This test was incorrect in the case where the method was inherited from a subclass. Which ironically is precisely what the function was supposed to test. Fixes #597
1 parent 8bd3d3e commit 0fc5220

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

pytest_django/plugin.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ def _classmethod_is_defined_at_leaf(cls, method_name):
277277
f = method.__func__
278278
except AttributeError:
279279
pytest.fail('%s.%s should be a classmethod' % (cls, method_name))
280-
if PY2 and not (inspect.ismethod(method) and method.__self__ is cls):
280+
if PY2 and not (inspect.ismethod(method) and
281+
inspect.isclass(method.__self__) and
282+
issubclass(cls, method.__self__)):
281283
pytest.fail('%s.%s should be a classmethod' % (cls, method_name))
282284
return f is not super_method.__func__
283285

tests/test_unittest.py

+73
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,79 @@ def test_pass(self):
141141
])
142142
assert result.ret == 1
143143

144+
def test_setUpClass_multiple_subclasses(self, django_testdir):
145+
django_testdir.create_test_module('''
146+
from django.test import TestCase
147+
148+
149+
class TestFoo(TestCase):
150+
@classmethod
151+
def setUpClass(cls):
152+
super(TestFoo, cls).setUpClass()
153+
154+
def test_shared(self):
155+
pass
156+
157+
158+
class TestBar(TestFoo):
159+
def test_bar1(self):
160+
pass
161+
162+
163+
class TestBar2(TestFoo):
164+
def test_bar21(self):
165+
pass
166+
''')
167+
168+
result = django_testdir.runpytest_subprocess('-v', '-s')
169+
result.stdout.fnmatch_lines([
170+
"*TestFoo::test_shared Creating test database for*",
171+
"PASSED",
172+
"*TestBar::test_bar1 PASSED",
173+
"*TestBar::test_shared PASSED",
174+
"*TestBar2::test_bar21 PASSED",
175+
"*TestBar2::test_shared PASSED*",
176+
])
177+
assert result.ret == 0
178+
179+
def test_setUpClass_skip(self, django_testdir):
180+
django_testdir.create_test_module('''
181+
from django.test import TestCase
182+
import pytest
183+
184+
185+
class TestFoo(TestCase):
186+
@classmethod
187+
def setUpClass(cls):
188+
if cls is TestFoo:
189+
raise pytest.skip("Skip base class")
190+
super(TestFoo, cls).setUpClass()
191+
192+
def test_shared(self):
193+
pass
194+
195+
196+
class TestBar(TestFoo):
197+
def test_bar1(self):
198+
pass
199+
200+
201+
class TestBar2(TestFoo):
202+
def test_bar21(self):
203+
pass
204+
''')
205+
206+
result = django_testdir.runpytest_subprocess('-v', '-s')
207+
result.stdout.fnmatch_lines([
208+
"*TestFoo::test_shared Creating test database for*",
209+
"SKIPPED",
210+
"*TestBar::test_bar1 PASSED",
211+
"*TestBar::test_shared PASSED",
212+
"*TestBar2::test_bar21 PASSED",
213+
"*TestBar2::test_shared PASSED*",
214+
])
215+
assert result.ret == 0
216+
144217
def test_multi_inheritance_setUpClass(self, django_testdir):
145218
django_testdir.create_test_module('''
146219
from django.test import TestCase

0 commit comments

Comments
 (0)