From 8e21ef59e9d42313bac2092143d885e1dccfee94 Mon Sep 17 00:00:00 2001 From: KTanmay1 Date: Thu, 13 Aug 2026 18:15:43 +0530 Subject: [PATCH] Fix pytest result parsing counting more tests than were run `test_pattern` uses `\s+` between the test id and the status token. `\s` matches newlines, so a test id ending one line pairs with a status token beginning the next. pytest's short summary emits exactly that shape for setup and teardown errors, whose lines carry no trailing reason: ERROR tests/test_smaz.py::test_one ERROR tests/test_smaz.py::test_two Line 1 ends in `::test_one`, line 2 begins with `ERROR`, and the pair matches. Chained across the block, N entries are counted as 2N-1. Observed on antirez_smaz (C -> Python) against an empty tree: 18 tests run, 35 counted. Reproduced standalone at 3 -> 5. Only entries with no trailing reason chain. Collection errors print `ERROR tests/x.py` with no `::` and never matched. Failures print `FAILED tests/x.py::test_y - AssertionError: ...`, so nothing chains onto them. A fully passing run is unaffected. Because Ni inflates while Ti does not, APR and AMPR are depressed on affected tasks; SR is unchanged. Fix: anchor the match to the start of a line and restrict the separator to spaces and tabs. Verified against PythonTestAnalyzer.analyze_output: 3 setup errors total=3 (was 5) rate=0.0% 2 pass 1 fail total=3 rate=66.7% all passing total=2 rate=100.0% This changes reported APR/AMPR on tasks with setup or teardown errors. --- RepoTransAgent/test_analyzer.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/RepoTransAgent/test_analyzer.py b/RepoTransAgent/test_analyzer.py index 78d2d8e..97d31e2 100644 --- a/RepoTransAgent/test_analyzer.py +++ b/RepoTransAgent/test_analyzer.py @@ -122,9 +122,12 @@ def analyze_output(self, stdout: str, stderr: str, return_code: int) -> Analysis tests = [] modules = {} - # Parse pytest output - test_pattern = r'(\S+)::\S+\s+(PASSED|FAILED|ERROR|SKIPPED)' - matches = re.findall(test_pattern, stdout) + # Parse pytest output. + # Anchor to the start of a line and keep the separator on one line: \s would + # match the newline, letting a test id at the end of a short-summary line pair + # with the status token that begins the next one. + test_pattern = r'^(\S+)::\S+[ \t]+(PASSED|FAILED|ERROR|SKIPPED)' + matches = re.findall(test_pattern, stdout, re.MULTILINE) for match in matches: test_file, status = match