Skip to content

Commit 3734a27

Browse files
authored
[5.4] Do not call TestCase.tearDown for skipped tests (#7236) (#7283)
[5.4] Do not call TestCase.tearDown for skipped tests (#7236)
2 parents b7b7292 + 551400e commit 3734a27

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

changelog/7215.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix regression where running with ``--pdb`` would call the ``tearDown`` methods of ``unittest.TestCase``
2+
subclasses for skipped tests.

src/_pytest/unittest.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def collect(self):
4141
if not getattr(cls, "__test__", True):
4242
return
4343

44-
skipped = getattr(cls, "__unittest_skip__", False)
44+
skipped = _is_skipped(cls)
4545
if not skipped:
4646
self._inject_setup_teardown_fixtures(cls)
4747
self._inject_setup_class_fixture()
@@ -89,7 +89,7 @@ def _make_xunit_fixture(obj, setup_name, teardown_name, scope, pass_self):
8989

9090
@pytest.fixture(scope=scope, autouse=True)
9191
def fixture(self, request):
92-
if getattr(self, "__unittest_skip__", None):
92+
if _is_skipped(self):
9393
reason = self.__unittest_skip_why__
9494
pytest.skip(reason)
9595
if setup is not None:
@@ -220,7 +220,7 @@ def runtest(self):
220220
# arguably we could always postpone tearDown(), but this changes the moment where the
221221
# TestCase instance interacts with the results object, so better to only do it
222222
# when absolutely needed
223-
if self.config.getoption("usepdb"):
223+
if self.config.getoption("usepdb") and not _is_skipped(self.obj):
224224
self._explicit_tearDown = self._testcase.tearDown
225225
setattr(self._testcase, "tearDown", lambda *args: None)
226226

@@ -301,3 +301,8 @@ def check_testcase_implements_trial_reporter(done=[]):
301301

302302
classImplements(TestCaseFunction, IReporter)
303303
done.append(1)
304+
305+
306+
def _is_skipped(obj) -> bool:
307+
"""Return True if the given object has been marked with @unittest.skip"""
308+
return bool(getattr(obj, "__unittest_skip__", False))

testing/test_unittest.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,40 @@ def test_2(self):
11931193
]
11941194

11951195

1196+
@pytest.mark.parametrize("mark", ["@unittest.skip", "@pytest.mark.skip"])
1197+
def test_pdb_teardown_skipped(testdir, monkeypatch, mark):
1198+
"""
1199+
With --pdb, setUp and tearDown should not be called for skipped tests.
1200+
"""
1201+
tracked = []
1202+
monkeypatch.setattr(pytest, "test_pdb_teardown_skipped", tracked, raising=False)
1203+
1204+
testdir.makepyfile(
1205+
"""
1206+
import unittest
1207+
import pytest
1208+
1209+
class MyTestCase(unittest.TestCase):
1210+
1211+
def setUp(self):
1212+
pytest.test_pdb_teardown_skipped.append("setUp:" + self.id())
1213+
1214+
def tearDown(self):
1215+
pytest.test_pdb_teardown_skipped.append("tearDown:" + self.id())
1216+
1217+
{mark}("skipped for reasons")
1218+
def test_1(self):
1219+
pass
1220+
1221+
""".format(
1222+
mark=mark
1223+
)
1224+
)
1225+
result = testdir.runpytest_inprocess("--pdb")
1226+
result.stdout.fnmatch_lines("* 1 skipped in *")
1227+
assert tracked == []
1228+
1229+
11961230
def test_async_support(testdir):
11971231
pytest.importorskip("unittest.async_case")
11981232

0 commit comments

Comments
 (0)