From 5ff0bb5a2bb2fe955f3cc02ac25fe60064d96d4b Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 9 Nov 2019 05:52:16 +0100 Subject: [PATCH 1/2] Monkeypatch pytest instead of Django to workaround pytest bug --- pytest_django/plugin.py | 34 +++++++++++++--------------------- tests/test_unittest.py | 18 +++++------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 898257cb5..b76ac8b3d 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -518,29 +518,21 @@ def _django_setup_unittest(request, django_db_blocker): yield return - request.getfixturevalue("django_db_setup") + from _pytest.unittest import TestCaseFunction - cls = request.node.cls + if "debug" in TestCaseFunction.runtest.__code__.co_names: + # Fix pytest (https://github.com/pytest-dev/pytest/issues/5991). + from _pytest.monkeypatch import MonkeyPatch - # Implement missing debug() wrapper/method for Django's TestCase (< 3.1.0). - # See pytest-dev/pytest-django#406. - import django - monkeypatch_debug = django.VERSION < (3, 1) - if monkeypatch_debug: - def _cleaning_debug(self): - testMethod = getattr(self, self._testMethodName) - skipped = getattr(self.__class__, "__unittest_skip__", False) or getattr( - testMethod, "__unittest_skip__", False - ) + def non_debugging_runtest(self): + self._testcase(result=self) - if not skipped: - self._pre_setup() - super(cls, self).debug() - if not skipped: - self._post_teardown() + mp_debug = MonkeyPatch() + mp_debug.setattr("_pytest.unittest.TestCaseFunction.runtest", non_debugging_runtest) - orig_debug = cls.debug - cls.debug = _cleaning_debug + request.getfixturevalue("django_db_setup") + + cls = request.node.cls with django_db_blocker.unblock(): if _handle_unittest_methods: @@ -555,8 +547,8 @@ def _cleaning_debug(self): else: yield - if monkeypatch_debug: - cls.debug = orig_debug + if mp_debug: + mp_debug.undo() @pytest.fixture(scope="function", autouse=True) diff --git a/tests/test_unittest.py b/tests/test_unittest.py index 1b4fe6459..985e868ed 100644 --- a/tests/test_unittest.py +++ b/tests/test_unittest.py @@ -458,7 +458,7 @@ def tearDown(self): assert result.ret == 0 -def test_debug_restored(django_testdir): +def test_debug_not_used(django_testdir): django_testdir.create_test_module( """ from django.test import TestCase @@ -468,22 +468,14 @@ def test_debug_restored(django_testdir): class TestClass1(TestCase): - def test_method(self): - pass - - - class TestClass2(TestClass1): - - def _pre_setup(self): - global pre_setup_count - pre_setup_count += 1 - super(TestClass2, self)._pre_setup() + def debug(self): + assert 0, "should not be called" def test_method(self): - assert pre_setup_count == 1 + pass """ ) result = django_testdir.runpytest_subprocess("--pdb") - result.stdout.fnmatch_lines(["*= 2 passed in *"]) + result.stdout.fnmatch_lines(["*= 1 passed in *"]) assert result.ret == 0 From df0c3d227b654a22d9dd79876bb115fd2edb568a Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 9 Nov 2019 05:55:13 +0100 Subject: [PATCH 2/2] fixup! Monkeypatch pytest instead of Django to workaround pytest bug --- pytest_django/plugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index b76ac8b3d..3eec1e953 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -521,7 +521,8 @@ def _django_setup_unittest(request, django_db_blocker): from _pytest.unittest import TestCaseFunction if "debug" in TestCaseFunction.runtest.__code__.co_names: - # Fix pytest (https://github.com/pytest-dev/pytest/issues/5991). + # Fix pytest (https://github.com/pytest-dev/pytest/issues/5991), only + # if "self._testcase.debug()" is being used (forward compatible). from _pytest.monkeypatch import MonkeyPatch def non_debugging_runtest(self): @@ -529,6 +530,8 @@ def non_debugging_runtest(self): mp_debug = MonkeyPatch() mp_debug.setattr("_pytest.unittest.TestCaseFunction.runtest", non_debugging_runtest) + else: + mp_debug = None request.getfixturevalue("django_db_setup")