mirror of
https://github.com/tbamud/tbamud.git
synced 2026-04-30 04:41:51 +02:00
CI: produce JUnit XML from Unity tests for GitHub test reporting
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/0bc0c851-36e7-4d13-a393-517477e66c73 Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d810782392
commit
73bda79fe6
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@@ -8,6 +8,8 @@ on:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
checks: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -24,3 +26,10 @@ jobs:
|
|||||||
- name: test
|
- name: test
|
||||||
working-directory: tests
|
working-directory: tests
|
||||||
run: make test
|
run: make test
|
||||||
|
- name: publish test results
|
||||||
|
uses: dorny/test-reporter@v1
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: Unity Tests
|
||||||
|
path: tests/test-results/*.xml
|
||||||
|
reporter: java-junit
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -100,3 +100,4 @@ tests/test_utils
|
|||||||
tests/test_random
|
tests/test_random
|
||||||
tests/test_interpreter
|
tests/test_interpreter
|
||||||
tests/test_class
|
tests/test_class
|
||||||
|
tests/test-results/
|
||||||
|
|||||||
@@ -66,38 +66,28 @@ test_class: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) \
|
|||||||
$(COMPILE) -o $@ $^ $(LIBS)
|
$(COMPILE) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Run all tests
|
# Run all tests and produce JUnit XML files in test-results/
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
test: $(TESTS)
|
test: $(TESTS)
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo "Running tbaMUD unit tests"
|
@echo "Running tbaMUD unit tests"
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
|
@mkdir -p test-results
|
||||||
@status=0; \
|
@status=0; \
|
||||||
if ./test_utils; then \
|
for t in $(TESTS); do \
|
||||||
echo "[PASS] test_utils"; \
|
./$$t > test-results/$$t.out 2>&1; \
|
||||||
|
rc=$$?; \
|
||||||
|
cat test-results/$$t.out; \
|
||||||
|
python3 unity_to_junit.py $$t test-results/$$t.xml < test-results/$$t.out; \
|
||||||
|
if [ $$rc -eq 0 ]; then \
|
||||||
|
echo "[PASS] $$t"; \
|
||||||
else \
|
else \
|
||||||
echo "[FAIL] test_utils"; \
|
echo "[FAIL] $$t"; \
|
||||||
status=1; \
|
|
||||||
fi; \
|
|
||||||
if ./test_random; then \
|
|
||||||
echo "[PASS] test_random"; \
|
|
||||||
else \
|
|
||||||
echo "[FAIL] test_random"; \
|
|
||||||
status=1; \
|
|
||||||
fi; \
|
|
||||||
if ./test_interpreter; then \
|
|
||||||
echo "[PASS] test_interpreter"; \
|
|
||||||
else \
|
|
||||||
echo "[FAIL] test_interpreter"; \
|
|
||||||
status=1; \
|
|
||||||
fi; \
|
|
||||||
if ./test_class; then \
|
|
||||||
echo "[PASS] test_class"; \
|
|
||||||
else \
|
|
||||||
echo "[FAIL] test_class"; \
|
|
||||||
status=1; \
|
status=1; \
|
||||||
fi; \
|
fi; \
|
||||||
|
done; \
|
||||||
exit $$status
|
exit $$status
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TESTS)
|
rm -f $(TESTS)
|
||||||
|
rm -rf test-results
|
||||||
|
|||||||
73
tests/unity_to_junit.py
Normal file
73
tests/unity_to_junit.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Convert Unity test-runner output to JUnit XML.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
./test_binary | python3 unity_to_junit.py <suite_name> <output.xml>
|
||||||
|
|
||||||
|
Unity emits one result line per test:
|
||||||
|
path/to/file.c:LINE:TEST_NAME:PASS
|
||||||
|
path/to/file.c:LINE:TEST_NAME:FAIL:message
|
||||||
|
path/to/file.c:LINE:TEST_NAME:IGNORE:message
|
||||||
|
followed by a summary line:
|
||||||
|
N Tests N Failures N Ignored
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
|
||||||
|
def parse_unity(lines):
|
||||||
|
tests = []
|
||||||
|
total = failures = ignored = 0
|
||||||
|
for line in lines:
|
||||||
|
line = line.rstrip("\n")
|
||||||
|
m = re.match(
|
||||||
|
r"^.+:\d+:([^:]+):(PASS|FAIL|IGNORE)(?::(.*))?$", line
|
||||||
|
)
|
||||||
|
if m:
|
||||||
|
name, result, message = m.group(1), m.group(2), m.group(3) or ""
|
||||||
|
tests.append((name, result, message))
|
||||||
|
continue
|
||||||
|
m2 = re.match(r"^(\d+) Tests (\d+) Failures (\d+) Ignored", line)
|
||||||
|
if m2:
|
||||||
|
total, failures, ignored = int(m2.group(1)), int(m2.group(2)), int(m2.group(3))
|
||||||
|
if not total:
|
||||||
|
total = len(tests)
|
||||||
|
failures = sum(1 for _, r, _ in tests if r == "FAIL")
|
||||||
|
ignored = sum(1 for _, r, _ in tests if r == "IGNORE")
|
||||||
|
return tests, total, failures, ignored
|
||||||
|
|
||||||
|
|
||||||
|
def build_xml(suite_name, tests, total, failures, ignored):
|
||||||
|
suite = ET.Element(
|
||||||
|
"testsuite",
|
||||||
|
name=suite_name,
|
||||||
|
tests=str(total),
|
||||||
|
failures=str(failures),
|
||||||
|
errors="0",
|
||||||
|
skipped=str(ignored),
|
||||||
|
)
|
||||||
|
for name, result, message in tests:
|
||||||
|
case = ET.SubElement(suite, "testcase", name=name, classname=suite_name)
|
||||||
|
if result == "FAIL":
|
||||||
|
f = ET.SubElement(case, "failure", message=message)
|
||||||
|
f.text = message
|
||||||
|
elif result == "IGNORE":
|
||||||
|
ET.SubElement(case, "skipped", message=message)
|
||||||
|
return ET.ElementTree(suite)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print(f"usage: {sys.argv[0]} <suite_name> <output.xml>", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
suite_name, output_file = sys.argv[1], sys.argv[2]
|
||||||
|
tests, total, failures, ignored = parse_unity(sys.stdin.readlines())
|
||||||
|
tree = build_xml(suite_name, tests, total, failures, ignored)
|
||||||
|
ET.indent(tree, space=" ")
|
||||||
|
tree.write(output_file, encoding="unicode", xml_declaration=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user