Files
nightclub-arcadia/tools/ci/report_tests.py
T
lennartandClaude Opus 5 f5b302b3e3 add a Makefile for the common commands, and a test reporter
The invocations in CLAUDE.md were correct but long, and retyping them is how
flags get dropped. `make check` is the gate a change should pass: Yarn compiles,
voice sheets are in sync, EditMode is green.

`make test` and `make build` depend on a `lock` target that fails if the Editor
has the project open, which removes the most common confusing failure. It
filters out AssetImportWorker children, which are not a second Editor.

tools/ci/report_tests.py parses the NUnit results and exits non-zero on failure,
because Unity documents no common exit-code definition across the components
under test — the XML is the authority, not $?.

`make merge-driver` configures UnityYAMLMerge for the .gitattributes rules added
earlier. Note the binary lives in the Editor bundle under Contents/Helpers, not
Contents/Tools as most guides say; there is no Tools directory in Unity 6 on
macOS.

Also ignores the local .test-results/ and build/ output.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-25 20:29:39 +02:00

45 lines
1.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""Summarise an NUnit results file and exit non-zero if anything failed.
Unity's own docs state there is no common exit-code definition across the
components under test, so the results XML is the authority, not $?.
"""
import sys
import xml.etree.ElementTree as ET
def main(path):
try:
root = ET.parse(path).getroot()
except FileNotFoundError:
print(f"no results at {path} — the run did not get far enough to write one")
return 1
except ET.ParseError as exc:
print(f"could not parse {path}: {exc}")
return 1
total = int(root.get("total") or 0)
passed = int(root.get("passed") or 0)
failed = int(root.get("failed") or 0)
skipped = int(root.get("skipped") or 0)
for case in root.iter("test-case"):
if case.get("result") == "Passed":
continue
print(f"FAIL {case.get('fullname')}")
message = case.find("failure/message")
if message is not None and message.text:
for line in message.text.strip().splitlines()[:6]:
print(f" {line}")
if total == 0:
print("no tests ran")
else:
print(f"{passed}/{total} passed" + (f", {skipped} skipped" if skipped else ""))
return 1 if failed else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else ".test-results/editmode.xml"))