Skip to content

Commit 5a9405b

Browse files
authored
Fix disabling/handling of unittest methods with pytest 4.2+ (#700)
Fixes #698.
1 parent 8654aab commit 5a9405b

File tree

5 files changed

+37
-17
lines changed

5 files changed

+37
-17
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ jobs:
2424
- python: 3.7
2525
env: TOXENV=py37-dj22-sqlite-coverage
2626

27+
# Explicitly test (older) pytest 4.1.
28+
- python: 3.7
29+
env: TOXENV=py37-dj21-sqlite-pytest41-coverage
30+
2731
- python: 3.6
2832
env: TOXENV=py36-djmaster-sqlite-coverage
2933

pytest_django/plugin.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import types
1313

1414
import pytest
15+
from pkg_resources import parse_version
1516

1617
from .django_compat import is_django_unittest # noqa
1718
from .fixtures import django_assert_num_queries # noqa
@@ -49,6 +50,9 @@
4950

5051
PY2 = sys.version_info[0] == 2
5152

53+
# pytest 4.2 handles unittest setup/teardown itself via wrapping fixtures.
54+
_handle_unittest_methods = parse_version(pytest.__version__) < parse_version("4.2")
55+
5256

5357
# ############### pytest hooks ################
5458

@@ -416,9 +420,9 @@ def _restore_class_methods(cls):
416420

417421

418422
def pytest_runtest_setup(item):
419-
if django_settings_is_configured() and is_django_unittest(item):
420-
cls = item.cls
421-
_disable_class_methods(cls)
423+
if _handle_unittest_methods:
424+
if django_settings_is_configured() and is_django_unittest(item):
425+
_disable_class_methods(item.cls)
422426

423427

424428
@pytest.fixture(autouse=True, scope="session")
@@ -508,16 +512,19 @@ def _cleaning_debug(self):
508512

509513
cls.debug = _cleaning_debug
510514

511-
_restore_class_methods(cls)
512-
cls.setUpClass()
513-
_disable_class_methods(cls)
514-
515-
def teardown():
515+
if _handle_unittest_methods:
516516
_restore_class_methods(cls)
517-
cls.tearDownClass()
518-
django_db_blocker.restore()
517+
cls.setUpClass()
518+
_disable_class_methods(cls)
519519

520-
request.addfinalizer(teardown)
520+
def teardown():
521+
_restore_class_methods(cls)
522+
cls.tearDownClass()
523+
django_db_blocker.restore()
524+
525+
request.addfinalizer(teardown)
526+
else:
527+
request.addfinalizer(django_db_blocker.restore)
521528

522529

523530
@pytest.fixture(scope="function", autouse=True)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def read(fname):
3131
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
3232
setup_requires=['setuptools_scm>=1.11.1'],
3333
install_requires=[
34-
'pytest>=3.6,!=4.2.0',
34+
'pytest>=3.6',
3535
'pathlib2;python_version<"3.4"',
3636
],
3737
extras_require={

tests/test_unittest.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
from django.test import TestCase
3+
from pkg_resources import parse_version
34

45
from pytest_django_test.app.models import Item
56

@@ -142,12 +143,19 @@ def test_pass(self):
142143
)
143144

144145
result = django_testdir.runpytest_subprocess("-v", "-s")
145-
result.stdout.fnmatch_lines(
146-
[
147-
"* ERROR at setup of TestFoo.test_pass *",
146+
expected_lines = [
147+
"* ERROR at setup of TestFoo.test_pass *",
148+
]
149+
if parse_version(pytest.__version__) < parse_version("4.2"):
150+
expected_lines += [
148151
"E *Failed: <class 'tpkg.test_the_test.TestFoo'>.setUpClass should be a classmethod", # noqa:E501
149152
]
150-
)
153+
else:
154+
expected_lines += [
155+
"E * TypeError: *",
156+
]
157+
158+
result.stdout.fnmatch_lines(expected_lines)
151159
assert result.ret == 1
152160

153161
def test_setUpClass_multiple_subclasses(self, django_testdir):
@@ -261,7 +269,6 @@ def test_multi_inheritance_setUpClass(self, django_testdir):
261269
django_testdir.create_test_module(
262270
"""
263271
from django.test import TestCase
264-
from .app.models import Item
265272
266273
# Using a mixin is a regression test, see #280 for more details:
267274
# https://github.com/pytest-dev/pytest-django/issues/280

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ deps =
2525
postgres: psycopg2-binary
2626
coverage: coverage-enable-subprocess
2727

28+
pytest41: pytest>=4.1,<4.2
29+
2830
setenv =
2931
PYTHONPATH = {toxinidir}:{env:PYTHONPATH:}
3032

0 commit comments

Comments
 (0)