Skip to content

Commit 6823ae9

Browse files
author
beyondgeeks
committed
Monkeypatch pytest instead of Django to workaround pytest bug (#782)
Fixes pytest-dev/pytest-django#772. Ref: pytest-dev/pytest#5996
1 parent 1e5afcc commit 6823ae9

File tree

2 files changed

+21
-34
lines changed

2 files changed

+21
-34
lines changed

Diff for: pytest_django/plugin.py

+16-21
Original file line numberDiff line numberDiff line change
@@ -518,29 +518,24 @@ def _django_setup_unittest(request, django_db_blocker):
518518
yield
519519
return
520520

521-
request.getfixturevalue("django_db_setup")
521+
from _pytest.unittest import TestCaseFunction
522522

523-
cls = request.node.cls
523+
if "debug" in TestCaseFunction.runtest.__code__.co_names:
524+
# Fix pytest (https://github.com/pytest-dev/pytest/issues/5991), only
525+
# if "self._testcase.debug()" is being used (forward compatible).
526+
from _pytest.monkeypatch import MonkeyPatch
524527

525-
# Implement missing debug() wrapper/method for Django's TestCase (< 3.1.0).
526-
# See pytest-dev/pytest-django#406.
527-
import django
528-
monkeypatch_debug = django.VERSION < (3, 1)
529-
if monkeypatch_debug:
530-
def _cleaning_debug(self):
531-
testMethod = getattr(self, self._testMethodName)
532-
skipped = getattr(self.__class__, "__unittest_skip__", False) or getattr(
533-
testMethod, "__unittest_skip__", False
534-
)
528+
def non_debugging_runtest(self):
529+
self._testcase(result=self)
535530

536-
if not skipped:
537-
self._pre_setup()
538-
super(cls, self).debug()
539-
if not skipped:
540-
self._post_teardown()
531+
mp_debug = MonkeyPatch()
532+
mp_debug.setattr("_pytest.unittest.TestCaseFunction.runtest", non_debugging_runtest)
533+
else:
534+
mp_debug = None
541535

542-
orig_debug = cls.debug
543-
cls.debug = _cleaning_debug
536+
request.getfixturevalue("django_db_setup")
537+
538+
cls = request.node.cls
544539

545540
with django_db_blocker.unblock():
546541
if _handle_unittest_methods:
@@ -555,8 +550,8 @@ def _cleaning_debug(self):
555550
else:
556551
yield
557552

558-
if monkeypatch_debug:
559-
cls.debug = orig_debug
553+
if mp_debug:
554+
mp_debug.undo()
560555

561556

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

Diff for: tests/test_unittest.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def tearDown(self):
458458
assert result.ret == 0
459459

460460

461-
def test_debug_restored(django_testdir):
461+
def test_debug_not_used(django_testdir):
462462
django_testdir.create_test_module(
463463
"""
464464
from django.test import TestCase
@@ -468,22 +468,14 @@ def test_debug_restored(django_testdir):
468468
469469
class TestClass1(TestCase):
470470
471-
def test_method(self):
472-
pass
473-
474-
475-
class TestClass2(TestClass1):
476-
477-
def _pre_setup(self):
478-
global pre_setup_count
479-
pre_setup_count += 1
480-
super(TestClass2, self)._pre_setup()
471+
def debug(self):
472+
assert 0, "should not be called"
481473
482474
def test_method(self):
483-
assert pre_setup_count == 1
475+
pass
484476
"""
485477
)
486478

487479
result = django_testdir.runpytest_subprocess("--pdb")
488-
result.stdout.fnmatch_lines(["*= 2 passed in *"])
480+
result.stdout.fnmatch_lines(["*= 1 passed in *"])
489481
assert result.ret == 0

0 commit comments

Comments
 (0)