Skip to content

feat: emit per-test JUnit XML from the clojure_test runner#105

Open
english wants to merge 1 commit into
mainfrom
english/junit
Open

feat: emit per-test JUnit XML from the clojure_test runner#105
english wants to merge 1 commit into
mainfrom
english/junit

Conversation

@english
Copy link
Copy Markdown
Contributor

@english english commented Jun 2, 2026

Summary

The clojure_test runner only reported a pass/fail exit code, so Bazel
generated a single stub JUnit result per target. The runner now emits structured
JUnit XML to $XML_OUTPUT_FILE, so Bazel surfaces one result per deftest
with timing and failure/error detail instead of a synthesised stub.

What changed

  • testrunner.clj hooks clojure.test's :begin-test-var / :end-test-var
    events to build one <testcase> per deftest (grouped into one
    <testsuite> per namespace), then serialises to $XML_OUTPUT_FILE.
  • Assertion failures → <failure>, uncaught exceptions → <error>, each with
    message + expected/actual or stacktrace.
  • Namespace-load failures and fixture exceptions surface as errored testcases
    rather than disappearing into the exit code.
  • XML is hand-rolled (no new deps) so the isolated AOT bootstrap keeps working;
    console output is unchanged.

In addition to producing the JUnit report, running bazel test with the --test_summary=detailed flag will have bazel output per-deftest results, including timing, like:

//test:ci_failure_demo_test.test                                         FAILED in 6.5s
    PASSED  ci-failure-demo-test.slow-demo (5.0s)
    PASSED  ci-failure-demo-test.passing-demo (0.0s)
    FAILED  ci-failure-demo-test.assertion-failure-demo (0.0s)
    ERROR   ci-failure-demo-test.uncaught-error-demo (0.0s)
    FAILED  ci-failure-demo-test.multiple-failures-demo (0.0s)
    FAILED  ci-failure-demo-test.property-failure-demo (0.0s)

Notes

  • <system-out> is deliberately omitted. The old path wrote no
    $XML_OUTPUT_FILE, so Bazel's stub generator
    (generate-xml.sh)
    embedded the full test.log in <system-out>; emitting our own XML drops
    that auto-embedded log. This matches Bazel's own
    AntXmlResultWriter
    (which leaves <system-out> empty), and the console log is still captured in
    test.log.

@english english force-pushed the english/junit branch 2 times, most recently from a3f395d to 128218e Compare June 2, 2026 13:50
## Summary

The `clojure_test` runner only reported a pass/fail exit code, so Bazel
synthesised a single stub result per target. The runner now emits structured
JUnit XML to `$XML_OUTPUT_FILE`, so Bazel surfaces **one result per `deftest`**
with timing and failure/error detail instead of a synthesised stub.

## What changed

- `testrunner.clj` hooks `clojure.test`'s `:begin-test-var` / `:end-test-var`
  events to build one `<testcase>` per `deftest` (grouped into one
  `<testsuite>` per namespace), then serialises to `$XML_OUTPUT_FILE`.
- Assertion failures → `<failure>`, uncaught exceptions → `<error>`, each with
  message + expected/actual or stacktrace.
- Namespace-load failures and fixture exceptions surface as errored testcases
  rather than disappearing into the exit code.
- XML is hand-rolled (no new deps) so the isolated AOT bootstrap keeps working;
  console output is unchanged.

## Notes

- `<system-out>` is deliberately omitted. The old path wrote no
  `$XML_OUTPUT_FILE`, so Bazel's stub generator
  ([`generate-xml.sh`](https://github.com/bazelbuild/bazel/blob/8.6.0/tools/test/generate-xml.sh))
  embedded the full `test.log` in `<system-out>`; emitting our own XML drops
  that auto-embedded log. This matches Bazel's own
  [`AntXmlResultWriter`](https://github.com/bazelbuild/bazel/blob/8.6.0/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/AntXmlResultWriter.java)
  (which leaves `<system-out>` empty), and the console log is still captured in
  `test.log`.
- New `testrunner-test` covers well-formedness, one-suite-per-namespace, count
  aggregation, and special-character escaping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@english english marked this pull request as ready for review June 2, 2026 17:56
@english english requested a review from a team June 2, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant