Free tool

JUnit XML, as a report people can read.

Drop the junit.xml or TEST-*.xml your CI left behind. Get the pass rate, every failure with its stack trace, the flaky and the slowest tests — then copy a Markdown summary for the pull request or send the whole report as a link.

junit.xml
1.9 KB
Test results.html
Paste JUnit XML on the left.

Publishes this report on Comma: one URL for the failing run that opens on any phone, comments pinned to the exact failure, and the next run’s results kept as a revision you can diff. Free, no card.

How the file is read

  • Status comes from the child of each <testcase>: <failure> is a failed assertion, <error> a crash before one, <skipped> a skip, and no child a pass.
  • Flaky tests are the ones Maven Surefire and Gradle retried: a pass with <flakyFailure>, or a failure with <rerunFailure>.
  • Suites are the <testsuite> that directly contains each test, so nested suites and several files pasted into one <testsuites> both work.
  • Counts are recomputed from the test cases. If the root’s tests="…" says otherwise, the report warns that the run was probably cut short.
  • Output from <system-out> and <system-err> is kept under the failure it belongs to.

Getting the XML

RunnerWrites JUnit XML with
pytestpytest --junitxml=junit.xml
Jestjest --reporters=default --reporters=jest-junit
Vitestvitest run --reporter=junit --outputFile=junit.xml
PlaywrightPLAYWRIGHT_JUNIT_OUTPUT_NAME=junit.xml npx playwright test --reporter=junit
Maventarget/surefire-reports/TEST-*.xml (default)
Gradlebuild/test-results/test/TEST-*.xml (default)
Gogotestsum --junitfile junit.xml
PHPUnitphpunit --log-junit junit.xml
RSpecrspec --format RspecJunitFormatter --out junit.xml
.NETdotnet test --logger "junit;LogFilePath=junit.xml"

When the failing run should be a link

The CI test tab works for people with a seat in the CI. The product manager waiting on the release, the contractor who owns the flaky test and the on-call engineer on their phone usually don’t have one — and an XML attachment is no help to any of them. Published to Comma, the report opens anywhere, people comment on the exact failure, and an agent can publish it from the pipeline on every run. More on the format in what JUnit XML is, and on sharing the runner’s own HTML report in how to share a JUnit report.

Questions

How do I view a JUnit XML file?
Drop the file (junit.xml, TEST-*.xml, results.xml) onto this page or paste its contents. It becomes a test report in your browser: totals and a pass-rate bar, every failure with its message and stack trace, the slowest tests, and each suite folded with its test cases. Nothing is uploaded.
Which test runners does it work with?
Anything that writes JUnit XML: pytest --junitxml, Jest with jest-junit, Vitest and Playwright's junit reporter, Maven Surefire and Gradle, go test via gotestsum, PHPUnit --log-junit, RSpec, Cypress, Robot Framework, .NET with JunitXml.TestLogger, and most CI tools that re-export results. The format has no formal schema, so the viewer reads the elements every runner agrees on and ignores the extra attributes.
How does it decide whether a test passed?
A <testcase> with a <failure> child failed (an assertion didn't hold), one with <error> errored (it crashed before an assertion — a fixture, a timeout, a refused connection), one with <skipped> was skipped, and one with none of those passed. Surefire's <flakyFailure> on a passing test marks it flaky: it failed, was re-run, and passed.
Why do the counts differ from the tests attribute in my file?
The viewer counts the <testcase> elements actually in the file instead of trusting tests="…" on the root. When they disagree the report says so — usually the run crashed or was killed and the file was truncated, or a tool wrote the attribute before all tests ran.
Can I merge several JUnit files?
Paste them inside one <testsuites> element and they are read as one report, with each <testsuite> kept as its own section. Suites nested inside suites (Jest and some Gradle setups) are grouped by the suite that directly contains each test.
Can I post the summary on a pull request?
Yes. “Copy Markdown” gives a GitHub-flavored summary — pass/fail counts and a table of failing tests with their messages — that pastes into a PR comment or appends to $GITHUB_STEP_SUMMARY. For the stack traces, publish the report and put the link in the comment.
Is my test output uploaded?
No. The XML is parsed and the report is built in your browser. It only leaves your machine if you click “Get a shareable link” and publish the report to Comma.

Related: XML to JSON · HTML viewer · Playwright report blank · what a flaky test is · all free tools