JUnit XML Viewer
Open a JUnit XML report — the format almost every test runner and CI system emits — and read it as a clean pass/fail tree instead of scrolling raw XML. Each suite shows its passed, failed, errored, and skipped counts, and every test case gets a colour-coded badge, its class name, and its run time, with failure messages and stack traces tucked into expandable details. Suites with failures open automatically so problems are front and centre. The report is parsed in your browser, so build artifacts never leave your machine.
How to use the JUnit XML Viewer
Paste the contents of a JUnit XML file into the box or load it directly. These files are usually written to a path like target/surefire-reports/*.xml, test-results/junit.xml, or wherever your CI is configured to collect them, and most frameworks produce them through a reporter flag such as --reporters junit, pytest's --junitxml, or a built-in option. The viewer accepts both shapes the format takes in the wild: a top-level <testsuites> element wrapping several suites, or a single <testsuite> as the root.
Once parsed, each suite becomes a collapsible block headed by its name and a compact tally — green for passed, red for failed, amber for errored, grey for skipped — plus the suite's reported run time. Inside, every <testcase> is listed with a status badge derived from its children: a case containing a <failure> is marked failed, one with an <error> is errored, one with <skipped> is skipped, and anything else passed. For the cases that did not pass, a "details" toggle reveals the failure message, its type, and the stack trace or assertion text captured in the element body.
The status line at the top totals everything: how many tests ran across how many suites, and the split between passed, failed, errored, and skipped. Suites that contain a failure or error are expanded by default so you land on the problems without clicking, while clean suites stay collapsed to keep the report short. Counts are computed from the actual test cases rather than trusted from the suite attributes, so a report whose summary numbers drifted out of sync with its body still tallies correctly here. Nested suites are de-duplicated so tests are never counted twice.
What the JUnit XML format is
The "JUnit XML" format is the closest thing the testing world has to a universal report format, and it is a quiet accident of history. JUnit, the Java unit-testing framework, did not really define it; the Ant and Maven build tools did, when they added XML reporters for JUnit results in the early 2000s. That schema — a tree of <testsuite> and <testcase> elements with attributes for counts and timings — turned out to be simple enough that everyone copied it. Today pytest, Jest, Mocha, PHPUnit, Go's test tooling, RSpec, NUnit, and dozens of others can all emit it, which is exactly why CI systems standardised on it for displaying results.
The structure is small. A <testsuite> groups related tests and carries attributes such as name, tests, failures, errors, skipped, time, and often a timestamp. Inside it, each <testcase> has a name, a classname identifying where it lives, and a time in seconds. A passing test is just an empty <testcase>. A failing one contains a <failure> child with a message and type and the assertion detail as text; an <error> marks an unexpected exception rather than a failed assertion; and a <skipped> child marks a test that did not run. Optional <system-out> and <system-err> elements capture console output. Several suites are commonly wrapped in a root <testsuites> element with roll-up totals.
The distinction between a failure and an error is worth knowing, because it changes how you triage. A failure means a test ran and an assertion did not hold — the code behaved, just not as expected. An error means the test could not complete: an exception was thrown, a fixture blew up, a timeout fired. Failures usually point at the code under test; errors often point at the test environment or the test itself. Because the format has no formal schema and each tool fills it in slightly differently, reports vary in which attributes are present and how counts are tallied, so reading the actual cases — rather than trusting the header numbers — is the reliable way to see what happened in a run.
Common use cases
- Triaging a CI failure. Open the report artifact from a red build and jump straight to the failed cases and their messages.
- Reading a report locally. Inspect a
junit.xmlyour test run produced without pushing it to a CI dashboard. - Spotting slow tests. Scan the per-case timings to find which tests dominate the run.
- Checking a reporter's output. Confirm a newly configured JUnit reporter is emitting the suites and counts you expect.