Skip to content

feat(test): capture stdout/stderr in JUnit reporter#35198

Open
lunadogbot wants to merge 1 commit into
mainfrom
claude/deno-issue-20152-i1d2hz
Open

feat(test): capture stdout/stderr in JUnit reporter#35198
lunadogbot wants to merge 1 commit into
mainfrom
claude/deno-issue-20152-i1d2hz

Conversation

@lunadogbot

Copy link
Copy Markdown
Contributor

Closes #20152.

Problem

The JUnit reporter dropped all test output. The captured stdout/stderr arrived as a single global stream with no way to tell which test or step produced it, so report_output was a no-op with a TODO.

Solution

Within a worker, tests run sequentially, so output between a test's Wait and Result belongs to that test — and the channel's existing stdio-sync mechanism already guarantees correct interleaving of output and lifecycle events. The LSP reporter already relies on this to attribute output to a current_test; this PR applies the same approach to the JUnit reporter.

  • Tag output with its stream. TestEvent::Output(Vec<u8>) becomes TestEvent::Output(TestStdioStream, Vec<u8>), where the new TestStdioStream enum distinguishes Stdout/Stderr. Each TestStream now records which stream it reads from.
  • Track the active test/step in the JUnit reporter. current_test is set on report_wait/report_step_wait and restored/cleared on the corresponding results (mirroring the LSP reporter's stack-like handling), so step output is attributed to the step and pre/post-step output to the parent test.
  • Emit the output. Captured bytes are appended (ANSI-stripped, as the JUnit reporter already strips color) to per-case system_out/system_err buffers and serialized as <system-out>/<system-err> elements — matching the convention used by other JUnit producers such as Vitest.
  • Updated the report_output trait signature across all reporters; pretty/dot/tap/compound/LSP ignore the stream and keep their prior behavior.

Example

Deno.test("captures stdout and stderr", () => {
  console.log("log line");
  console.error("error line");
});
<testcase name="captures stdout and stderr" classname="./main.ts" time="0.019" line="1" col="6">
    <system-out>log line
</system-out>
    <system-err>error line
</system-err>
</testcase>

Tests

  • New spec test junit_capture_output covering stdout, stderr, and per-step attribution.
  • Updated junit and junit_multiple_test_files .out files, whose existing console.log/console.error tests now show captured output.
  • Verified hide_stacktraces, junit_nested, junit_console_formatting, and the junit_path integration test are unaffected.

https://claude.ai/code/session_013BQKi6tsSyAeFT3UsBgAfR


Generated by Claude Code

The JUnit reporter previously dropped all test output because the
captured stdout/stderr was a single global stream with no way to tell
which test or step produced it.

Tag each `TestEvent::Output` with the stream it came from
(`TestStdioStream::Stdout`/`Stderr`) and have the JUnit reporter track
the currently-running test/step (mirroring the existing LSP reporter).
Output is then attributed to the active test case and emitted as
`<system-out>`/`<system-err>` elements, matching the convention used by
other JUnit producers like Vitest.

Closes #20152
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.

JUnit: Capture stdout/stderr

2 participants