From 759239a7f7f7c02e5b4a16959a569ef4e0fb23aa Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 13 Dec 2020 09:51:38 -0300 Subject: [PATCH 1/2] Add support for --pdb in subtests Fix #22 --- CHANGELOG.rst | 7 +++++ pytest_subtests.py | 10 +++++++ tests/test_subtests.py | 60 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8555ce9..56efc18 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ CHANGELOG ========= +0.4.0 (2020-12-13) +------------------ + +* Add support for ``--pdb`` (`#22`_). + +.. _#22: https://github.com/pytest-dev/pytest-subtests/issues/22 + 0.3.2 (2020-08-01) ------------------ diff --git a/pytest_subtests.py b/pytest_subtests.py index 33d71e2..e66bca9 100644 --- a/pytest_subtests.py +++ b/pytest_subtests.py @@ -11,6 +11,7 @@ from _pytest.outcomes import OutcomeException from _pytest.reports import TestReport from _pytest.runner import CallInfo +from _pytest.runner import check_interactive_exception from _pytest.unittest import TestCaseFunction if sys.version_info[:2] < (3, 7): @@ -80,6 +81,10 @@ def _addSubTest(self, test_case, test, exc_info): sub_report = SubTestReport.from_item_and_call(item=self, call=call_info) sub_report.context = SubTestContext(msg, dict(test.params)) self.ihook.pytest_runtest_logreport(report=sub_report) + if check_interactive_exception(call_info, sub_report): + self.ihook.pytest_exception_interact( + node=self, call=call_info, report=sub_report + ) def pytest_configure(config): @@ -174,6 +179,11 @@ def test(self, msg=None, **kwargs): with self.suspend_capture_ctx(): self.ihook.pytest_runtest_logreport(report=sub_report) + if check_interactive_exception(call_info, sub_report): + self.ihook.pytest_exception_interact( + node=self.item, call=call_info, report=sub_report + ) + def make_call_info(exc_info, *, start, stop, duration, when): try: diff --git a/tests/test_subtests.py b/tests/test_subtests.py index 415abee..a666870 100644 --- a/tests/test_subtests.py +++ b/tests/test_subtests.py @@ -307,3 +307,63 @@ def test(subtests, {fixture}): result.stdout.fnmatch_lines( ["*1 passed*",] ) + + +class TestDebugging: + """Check --pdb support for subtests fixture and TestCase.subTest.""" + + class _FakePdb: + """ + Fake debugger class implementation that tracks which methods were called on it. + """ + + quitting = False + calls = [] + + def __init__(self, *args, **kwargs): + self.calls.append("init") + + def reset(self): + self.calls.append("reset") + + def interaction(self, *args): + self.calls.append("interaction") + + @pytest.fixture(autouse=True) + def cleanup_calls(self): + self._FakePdb.calls.clear() + + def test_pdb_fixture(self, testdir, monkeypatch): + testdir.makepyfile( + """ + def test(subtests): + with subtests.test(): + assert 0 + """ + ) + self.runpytest_and_check_pdb(testdir, monkeypatch) + + def test_pdb_unittest(self, testdir, monkeypatch): + testdir.makepyfile( + """ + from unittest import TestCase + class Test(TestCase): + def test(self): + with self.subTest(): + assert 0 + """ + ) + self.runpytest_and_check_pdb(testdir, monkeypatch) + + def runpytest_and_check_pdb(self, testdir, monkeypatch): + # Install the fake pdb implementation in pytest_subtests so we can reference + # it in the command line (any module would do). + import pytest_subtests + + monkeypatch.setattr(pytest_subtests, "_CustomPdb", self._FakePdb, raising=False) + result = testdir.runpytest("--pdb", "--pdbcls=pytest_subtests:_CustomPdb") + + # Ensure pytest entered in debugging mode when encountering the failing + # assert. + result.stdout.fnmatch_lines("*entering PDB*") + assert self._FakePdb.calls == ["init", "reset", "interaction"] From 8dad5363a1ac32bcfc2589cbf5819250b07e4bfa Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 13 Dec 2020 10:19:17 -0300 Subject: [PATCH 2/2] Ignore warning about using private pytest classes In pytest 6.2 we now get a warning whenever we are using a private class; pytest-subtests needs to dig into the internals to do its job so this is unavoidable. --- README.rst | 15 +++++++++++++++ tests/test_subtests.py | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/README.rst b/README.rst index 3c44383..a3abf7d 100644 --- a/README.rst +++ b/README.rst @@ -40,6 +40,21 @@ Requirements * ``Python`` >= 3.5. * ``pytest`` >= 4.4. +pytest 6.2+ +^^^^^^^^^^^ + +``pytest 6.2`` now issues a warning when internal classes are used by third-party code, +which is the case for ``pytest-subtests`` which needs to use some internal classes +to integrate with other pytest features (such as capturing and debugging). + +For now users can ignore those warnings by adding this to their configuration file: + +.. code-block:: ini + + [pytest] + filterwarnings = + ignore:A private pytest class or function was used.:PytestDeprecationWarning + Installation ------------ diff --git a/tests/test_subtests.py b/tests/test_subtests.py index a666870..101fd35 100644 --- a/tests/test_subtests.py +++ b/tests/test_subtests.py @@ -3,6 +3,20 @@ import pytest +@pytest.fixture(autouse=True) +def ignore_private_class_warning(testdir): + """ + Make every test in this file ignore the warning about using private pytest classes; + It is a risk we are willing to take in this plugin. + """ + testdir.makeini( + """ + [pytest] + filterwarnings = ignore:A private pytest class + """ + ) + + @pytest.mark.parametrize("mode", ["normal", "xdist"]) class TestFixture: """