Summary
Add --report-json <file> to write machine-readable JSON results (summary counts + per-test records). Lets scripts, dashboards and bots consume bashunit output without parsing human text or XML.
Motivation
JUnit XML and HTML exist, but JSON is the friendliest format for custom tooling (jq, GitHub Action summaries, flaky-test trackers). Verified missing: grep -- --report-json src/*.sh → none.
Proposed API
bashunit --report-json report.json tests/
Proposed schema (keep stable + documented):
{
"summary": { "total": 3, "passed": 2, "failed": 1, "skipped": 0, "incomplete": 0, "duration_ms": 42 },
"tests": [
{ "file": "tests/math_test.sh", "name": "it adds", "status": "passed", "duration_ms": 5 },
{ "file": "tests/math_test.sh", "name": "it divides", "status": "failed", "duration_ms": 3,
"message": "Expected 2 but got 3" }
]
}
status ∈ passed|failed|skipped|incomplete.
- Must emit valid JSON — carefully escape test names/messages (quotes, backslashes, newlines). No external
jq dependency; escape in pure Bash.
Files
- Report writer:
src/reports.sh (mirror JUnit writer; add a JSON-string escape helper).
- Flag parsing:
src/globals.sh.
- Docs:
docs/command-line.md + document the schema.
- Tests:
tests/unit/ (new reports_json_test.sh) + acceptance smoke test. If available, validate with jq . report.json in the test (guard when jq absent).
TDD steps
- RED: run with 1 pass + 1 fail; JSON file parses and
.summary.total==2, .summary.failed==1, failed test has a message.
- RED: a test name containing a
" and a newline round-trips as valid JSON.
- GREEN: minimal emitter + escape helper.
- REFACTOR: share plumbing with other reporters; verify under
--parallel.
Acceptance criteria
Constraints
- Bash 3.0+ only. See
.claude/rules/bash-style.md.
- Must pass
make sa, make lint, shfmt -w ., ./bashunit tests/, ./bashunit --parallel tests/.
Summary
Add
--report-json <file>to write machine-readable JSON results (summary counts + per-test records). Lets scripts, dashboards and bots consume bashunit output without parsing human text or XML.Motivation
JUnit XML and HTML exist, but JSON is the friendliest format for custom tooling (jq, GitHub Action summaries, flaky-test trackers). Verified missing:
grep -- --report-json src/*.sh→ none.Proposed API
Proposed schema (keep stable + documented):
{ "summary": { "total": 3, "passed": 2, "failed": 1, "skipped": 0, "incomplete": 0, "duration_ms": 42 }, "tests": [ { "file": "tests/math_test.sh", "name": "it adds", "status": "passed", "duration_ms": 5 }, { "file": "tests/math_test.sh", "name": "it divides", "status": "failed", "duration_ms": 3, "message": "Expected 2 but got 3" } ] }status∈passed|failed|skipped|incomplete.jqdependency; escape in pure Bash.Files
src/reports.sh(mirror JUnit writer; add a JSON-string escape helper).src/globals.sh.docs/command-line.md+ document the schema.tests/unit/(newreports_json_test.sh) + acceptance smoke test. If available, validate withjq . report.jsonin the test (guard whenjqabsent).TDD steps
.summary.total==2,.summary.failed==1, failed test has amessage."and a newline round-trips as valid JSON.--parallel.Acceptance criteria
--report-json <file>writes valid, schema-stable JSON.--parallel.Constraints
.claude/rules/bash-style.md.make sa,make lint,shfmt -w .,./bashunit tests/,./bashunit --parallel tests/.