Test reporter
A test reporter is the part of a test runner that turns its events into output. The runner executes tests and decides what passed. The reporter listens (run started, test finished, run complete) and writes the result somewhere: the terminal, a JUnit XML file, JSON, or an HTML report.
Reporters are pluggable, so the same run can produce several outputs. That's the normal setup, not an advanced one.
The usual three
| Reporter type | Who reads it | Example output |
|---|---|---|
| Console | Whoever is watching the job | Dots, a list, a summary line |
| JUnit XML | The CI system, the code host | junit.xml for test tabs and PR checks |
| HTML | Reviewers, QA, PMs, the on-call | report.html or a playwright-report/ folder |
JSON reporters (--json in Jest, json in Playwright) are a fourth,
mostly for your own scripts and dashboards.
How each runner configures them
Jest — a reporters array. Setting it replaces the defaults, so keep
"default":
reporters: ["default", ["jest-junit", { outputDirectory: "reports" }]];
Vitest — repeat --reporter, or set reporters in the config:
vitest run --reporter=default --reporter=junit --outputFile.junit=junit.xml
Playwright — a list of [name, options] tuples:
reporter: [
["list"],
["junit", { outputFile: "results/junit.xml" }],
["html", { open: "never" }],
],
pytest — flags combine: --junitxml=junit.xml is built in,
--html=report.html --self-contained-html comes from the pytest-html
plugin.
Mocha and Cypress — --reporter takes one reporter. To get more,
wrap them with mocha-multi-reporters or cypress-multi-reporters.
Go — go test has no reporter plugins, only -json. Tools like
gotestsum --junitfile junit.xml read that stream and write the other
formats.
.NET — loggers: dotnet test --logger trx --logger "junit" (the
second one from the JunitXml.TestLogger package).
Where reporters go wrong
- The defaults disappear. Jest and Playwright replace the default reporter when you configure one. The terminal goes quiet.
- The CLI overrides the config. A
--reporteror--reportersflag in a CI script replaces the configured list rather than adding to it. See Jest HTML report not generated. - The HTML report isn't one file. Playwright, Allure, Vitest and jest-html-reporters write a folder, and the page loads its data from it. Send only the HTML and it opens blank. See self-contained HTML.
- The report never leaves CI. It's uploaded as a build artifact, behind a login, and expires under retention.
The HTML report is the one people read
JUnit XML tells CI a test failed. The HTML report shows why: the assertion
diff, the screenshot, the trace, the timing. It's also the output most
likely to be stuck in a zip. Publishing it to a link, with each run as a
revision of the same page, turns it into something a team can discuss.
Comma does that with one curl from CI (publish from CI), and
the JUnit XML viewer turns a junit.xml into an
HTML report when the runner doesn't have one.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.