JUnit XML reporter — an additive artifact reporter, not a stdout format. Enabled with
--junit[=<path>], it accumulates a <testcase> per testEnd and writes the document at
run end, while whichever --reporter is active keeps owning stdout. That split matters:
CI wants a readable log and a machine-readable file, and it's what --coverage=lcov
already does for coverage artifacts.
Cases live on the instance (not on context), and the instance is shared across concurrent
groups, so one document covers the whole run. onRunStart resets it for watch reruns.
import type { ReporterContext } from './types.ts'; import type { TestDetails } from './types.ts'; // Defined, not invoked: onRunEnd writes junit.xml to disk. async function example(context: ReporterContext, details: TestDetails) { const reporter = new JUnitReporter(); reporter.onRunStart(); reporter.onTestEnd(context, details); // one <testcase> recorded await reporter.onRunEnd(context, { durationMs: 40 }); // document written to outputPath(context) }
onRunEnd(context: ReporterContext,_info: RunEndInfo): Promise<void>
Serializes the accumulated cases and writes the XML document to disk.
import type { ReporterContext } from './types.ts'; // Defined, not invoked: writes the XML document to disk. async function example(reporter: JUnitReporter, context: ReporterContext) { await reporter.onRunEnd(context, { durationMs: 40 }); // "# wrote JUnit report to tmp/junit.xml" on the run's output }
onRunStart(): void
Drops cases from any previous run so watch reruns start clean.
const reporter = new JUnitReporter(); reporter.onRunStart(); // cases recorded by a previous watch-mode run are gone
onTestEnd(context: ReporterContext,details: TestDetails): void
Accumulates one <testcase>; the document is written once at run end.
import type { ReporterContext } from './types.ts'; const reporter = new JUnitReporter(); reporter.onTestEnd({} as ReporterContext, { status: 'passed', fullName: ['Math', 'adds'], runtime: 2 }); // recorded as <testcase name="adds" classname="Math"/> (context is only read for failures)
xml(): string
The XML document as it stands. onRunEnd writes exactly this to disk; the JS API reads it
back so a caller can ship the report somewhere other than the filesystem.
const reporter = new JUnitReporter(); reporter.xml().startsWith('<?xml'); // true — an empty but well-formed document