From 13c6f6291c047087ffeeaf55e105d3de4dcf00d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:53:27 +0000 Subject: [PATCH] fix: add time attributes to JUnit XML to eliminate NaNms in test reporter Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/8d948e86-1d59-496f-a317-7fd9294fcad8 Co-authored-by: welcor <357770+welcor@users.noreply.github.com> --- tests/Makefile.in | 5 ++++- tests/unity_to_junit.py | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/Makefile.in b/tests/Makefile.in index f2c6286..c93cc0f 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -75,10 +75,13 @@ test: $(TESTS) @mkdir -p test-results @status=0; \ for t in $(TESTS); do \ + t_start=$$(date +%s%3N); \ ./$$t > test-results/$$t.out 2>&1; \ rc=$$?; \ + t_end=$$(date +%s%3N); \ + elapsed=$$(awk "BEGIN{printf \"%.3f\", ($$t_end - $$t_start)/1000}"); \ cat test-results/$$t.out; \ - python3 unity_to_junit.py $$t test-results/$$t.xml < test-results/$$t.out; \ + python3 unity_to_junit.py $$t test-results/$$t.xml "$$elapsed" < test-results/$$t.out; \ if [ $$rc -eq 0 ]; then \ echo "[PASS] $$t"; \ else \ diff --git a/tests/unity_to_junit.py b/tests/unity_to_junit.py index be5ee01..1f1feb9 100644 --- a/tests/unity_to_junit.py +++ b/tests/unity_to_junit.py @@ -2,7 +2,7 @@ """Convert Unity test-runner output to JUnit XML. Usage: - ./test_binary | python3 unity_to_junit.py + ./test_binary | python3 unity_to_junit.py [elapsed_seconds] Unity emits one result line per test: path/to/file.c:LINE:TEST_NAME:PASS @@ -39,7 +39,9 @@ def parse_unity(lines): return tests, total, failures, ignored -def build_xml(suite_name, tests, total, failures, ignored): +def build_xml(suite_name, tests, total, failures, ignored, elapsed): + # Distribute total time evenly across tests for per-testcase timing. + per_test = round(elapsed / total, 6) if total else 0.0 suite = ET.Element( "testsuite", name=suite_name, @@ -47,9 +49,13 @@ def build_xml(suite_name, tests, total, failures, ignored): failures=str(failures), errors="0", skipped=str(ignored), + time=f"{elapsed:.6f}", ) for name, result, message in tests: - case = ET.SubElement(suite, "testcase", name=name, classname=suite_name) + case = ET.SubElement( + suite, "testcase", + name=name, classname=suite_name, time=f"{per_test:.6f}", + ) if result == "FAIL": f = ET.SubElement(case, "failure", message=message) f.text = message @@ -59,12 +65,13 @@ def build_xml(suite_name, tests, total, failures, ignored): def main(): - if len(sys.argv) != 3: - print(f"usage: {sys.argv[0]} ", file=sys.stderr) + if len(sys.argv) < 3 or len(sys.argv) > 4: + print(f"usage: {sys.argv[0]} [elapsed_seconds]", file=sys.stderr) sys.exit(1) suite_name, output_file = sys.argv[1], sys.argv[2] + elapsed = float(sys.argv[3]) if len(sys.argv) == 4 else 0.0 tests, total, failures, ignored = parse_unity(sys.stdin.readlines()) - tree = build_xml(suite_name, tests, total, failures, ignored) + tree = build_xml(suite_name, tests, total, failures, ignored, elapsed) ET.indent(tree, space=" ") tree.write(output_file, encoding="unicode", xml_declaration=True)