Skip to content

Commit f2be8d4

Browse files
committed
subtests: fix inconcistent handling of non-string messages
1 parent 4b820f0 commit f2be8d4

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ Ralf Schmitt
384384
Ralph Giles
385385
Ram Rachum
386386
Ran Benita
387+
Randy Döring
387388
Raphael Castaneda
388389
Raphael Pierzina
389390
Rafal Semik

changelog/14195.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed an issue where non-string messages passed to `unittest.TestCase.subTest()` are not printed.

src/_pytest/unittest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from typing import Any
1717
from typing import TYPE_CHECKING
1818
from unittest import TestCase
19+
from unittest.case import _subtest_msg_sentinel # type: ignore[attr-defined]
1920

2021
import _pytest._code
2122
from _pytest._code import ExceptionInfo
@@ -427,7 +428,7 @@ def addSubTest(
427428
when="call",
428429
_ispytest=True,
429430
)
430-
msg = test._message if isinstance(test._message, str) else None # type: ignore[attr-defined]
431+
msg = None if test._message is _subtest_msg_sentinel else str(test._message) # type: ignore[attr-defined]
431432
report = self.ihook.pytest_runtest_makereport(item=self, call=call_info)
432433
sub_report = SubtestReport._new(
433434
report,

testing/test_subtests.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,30 @@ def test_foo(subtests):
373373
)
374374

375375

376+
def test_msg_not_a_string(
377+
pytester: pytest.Pytester, monkeypatch: pytest.MonkeyPatch
378+
) -> None:
379+
monkeypatch.setenv("COLUMNS", "120")
380+
pytester.makepyfile(
381+
"""
382+
def test_int_msg(subtests):
383+
with subtests.test(42):
384+
assert False, "subtest failure"
385+
386+
def test_no_msg(subtests):
387+
with subtests.test():
388+
assert False, "subtest failure"
389+
"""
390+
)
391+
result = pytester.runpytest()
392+
result.stdout.fnmatch_lines(
393+
[
394+
"SUBFAILED[[]42[]] test_msg_not_a_string.py::test_int_msg - AssertionError: subtest failure",
395+
"SUBFAILED(<subtest>) test_msg_not_a_string.py::test_no_msg - AssertionError: subtest failure",
396+
]
397+
)
398+
399+
376400
@pytest.mark.parametrize("flag", ["--last-failed", "--stepwise"])
377401
def test_subtests_last_failed_step_wise(pytester: pytest.Pytester, flag: str) -> None:
378402
"""Check that --last-failed and --step-wise correctly rerun tests with failed subtests."""
@@ -622,6 +646,32 @@ def test_foo(self):
622646
"SUBSKIPPED[[]subtest 1[]] [[]1[]] *.py:*: skip subtest 1"
623647
)
624648

649+
def test_msg_not_a_string(
650+
self, pytester: pytest.Pytester, monkeypatch: pytest.MonkeyPatch
651+
) -> None:
652+
monkeypatch.setenv("COLUMNS", "120")
653+
pytester.makepyfile(
654+
"""
655+
from unittest import TestCase
656+
657+
class T(TestCase):
658+
def test_int_msg(self):
659+
with self.subTest(42):
660+
assert False, "subtest failure"
661+
662+
def test_no_msg(self):
663+
with self.subTest():
664+
assert False, "subtest failure"
665+
"""
666+
)
667+
result = pytester.runpytest()
668+
result.stdout.fnmatch_lines(
669+
[
670+
"SUBFAILED[[]42[]] test_msg_not_a_string.py::T::test_int_msg - AssertionError: subtest failure",
671+
"SUBFAILED(<subtest>) test_msg_not_a_string.py::T::test_no_msg - AssertionError: subtest failure",
672+
]
673+
)
674+
625675

626676
class TestCapture:
627677
def create_file(self, pytester: pytest.Pytester) -> None:

0 commit comments

Comments
 (0)