Skip to content

Commit ce31856

Browse files
committed
failed test should be reported rather than skipped and add tests
1 parent f68afca commit ce31856

4 files changed

Lines changed: 43 additions & 13 deletions

File tree

Lib/test/libregrtest/findtests.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ def list_cases(tests: TestTuple, *,
105105
print(count(len(skipped), "test"), "skipped:", file=stderr)
106106
printlist(skipped, file=stderr)
107107

108+
class _ModuleLoadFailed(Exception):
109+
"""The test module failed to load; its test cases are unknown."""
110+
111+
108112
def collect_cases(tests: TestTuple, *,
109113
match_tests: TestFilter | None = None,
110114
test_dir: StrPath | None = None
@@ -124,16 +128,23 @@ def collect_cases(tests: TestTuple, *,
124128
except unittest.SkipTest:
125129
skipped.append(test_name)
126130
continue
131+
except _ModuleLoadFailed:
132+
# The module failed to load. Run it as a whole, so that the
133+
# error is reported as in the normal mode.
134+
result[test_name] = [test_name]
135+
continue
127136
if cases:
128137
result[test_name] = cases
129138
return result, skipped
130139

131140
def _collect_cases(suite: unittest.TestSuite, out: list[str]) -> None:
132141
for test in suite:
133-
if isinstance(test, unittest.loader._FailedTest): # type: ignore[attr-defined]
134-
continue
135142
if isinstance(test, unittest.TestSuite):
136143
_collect_cases(test, out)
144+
elif isinstance(test, unittest.loader._FailedTest): # type: ignore[attr-defined]
145+
# The test module failed to load. Its test cases are
146+
# unknown: let the caller run the whole module.
147+
raise _ModuleLoadFailed
137148
elif isinstance(test, unittest.TestCase):
138149
if match_test(test):
139150
out.append(test.id())

Lib/test/libregrtest/main.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,14 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
558558
selected,
559559
match_tests=self.match_tests,
560560
test_dir=self.test_dir)
561-
case_groups = tuple(
562-
(module_name, tuple(cases))
563-
for module_name, cases in cases_by_module.items()
564-
)
565-
if not case_groups:
566-
self.log("No test cases found")
567-
return 0
561+
case_groups = []
562+
for module_name in selected:
563+
cases = cases_by_module.get(module_name)
564+
if cases:
565+
case_groups.append((module_name, tuple(cases)))
566+
else:
567+
case_groups.append((module_name, (module_name,)))
568+
case_groups = tuple(case_groups)
568569
case_ids = tuple(
569570
case_id for _, cases in case_groups for case_id in cases
570571
)

Lib/test/libregrtest/run_workers.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,7 @@ def create_worker_runtests(self, test_name: TestName,
274274
) -> WorkerRunTests:
275275
kwargs: dict[str, Any] = {}
276276

277-
if module_name is not None:
278-
# single_process_per_case mode: run a single test case
279-
# (test_name is a case ID) inside its module.
277+
if module_name is not None and test_name != module_name:
280278
tests = (module_name,)
281279
kwargs['match_tests'] = [(test_name, True)]
282280
else:
@@ -426,7 +424,7 @@ def run(self) -> None:
426424
finally:
427425
self.test_name = _NOT_RUNNING
428426
mp_result.result.duration = time.monotonic() - self.start_time
429-
if single_process_per_case:
427+
if single_process_per_case and test_name != module_name:
430428
# Report the test case, not the test module
431429
mp_result.result.test_name = test_name
432430
self.output.put((False, mp_result))

Lib/test/test_regrtest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,26 @@ def test_fail(self):
24272427
self.assertIn(f'{testname}.Tests.test_pass passed', output)
24282428
self.check_line(output, '1 test OK.', regex=False)
24292429

2430+
def test_single_process_per_case_import_error(self):
2431+
testname = self.create_test(code='raise ImportError("boom")')
2432+
2433+
output = self.run_tests('--single-process-per-case', testname,
2434+
exitcode=EXITCODE_BAD_TEST)
2435+
self.check_executed_tests(output, [testname], failed=[testname],
2436+
stats=0)
2437+
self.assertNotIn('_FailedTest', output)
2438+
2439+
def test_single_process_per_case_skipped_module(self):
2440+
code = textwrap.dedent("""
2441+
import unittest
2442+
raise unittest.SkipTest("nope")
2443+
""")
2444+
testname = self.create_test(code=code)
2445+
2446+
output = self.run_tests('--single-process-per-case', testname)
2447+
self.check_executed_tests(output, [testname],
2448+
skipped=[testname], stats=0)
2449+
24302450

24312451
def test_verbose3(self):
24322452
code = textwrap.dedent(r"""

0 commit comments

Comments
 (0)