ToolJovia
Developer

JUnit XML Report Merger

Combine local legacy JUnit XML suites into one report ZIP while preserving every suite occurrence, original file and source-order evidence.

✓ Browser-local processing
1–20 files, up to 500 KiB each and 2 MiB combined. Selected flat, namespace-free legacy JUnit XML only.

Loading tool…

How to use JUnit XML Report Merger

Collect selected test-result files into one reviewable XML report without uploading logs or running tests. Each accepted suite is copied from its original source interval. Duplicate names remain separate, source counters stay authored, and no combined wall time or pass certificate is invented.

  1. Choose the actual XML report files in the order you want their suites included. Load example provides two original local reports. No directory, test command or URL is accessed.
  2. Run to validate the selected XML profile and inspect file, suite and testcase occurrence counts. Repeated names and multiple outcome elements are retained as source evidence.
  3. Download the ZIP. Extract merged-junit.xml for your own compatible report consumer. The evidence file records original attributes, source intervals and exact-byte hashes; sources/report-NNN.xml preserves every original file.
  4. Review the source logs before sharing and test the merged report in your own CI publisher. Reset removes the current app result; this tool does not publish, execute or certify tests.

Good to know

  • Selected legacy XML only: one unqualified testsuite root or a flat testsuites wrapper per file. Nested suites, namespace declarations/qualified extension elements, DTD/entity declarations and processing instructions except an initial XML 1.0/UTF-8 declaration refuse the entire operation. Open Test Reporting and arbitrary test-result dialects are unsupported. This is not runtime XSD validation.
  • Choose 1–20 nonempty actual files, at most 512,000 bytes each and 2,097,152 bytes combined. Each filename is a single line up to 200 UTF-16 units and is evidence only, never an archive path. Strict UTF-8 and one optional initial BOM are required. All original file bytes, including BOM and CRLF, remain in the ZIP.
  • Across inputs: at most 20,000 element starts, 40,000 native parsed nodes, 200 suite occurrences and 5,000 testcase occurrences; 60 input element levels, 1,000 attributes per element, names up to 100 units and attribute values up to 10,000 units. Suite name/tests/failures/errors and testcase name metadata are required; supplied counters use nonnegative integer strings up to 32 digits.
  • Accepted suite substrings are copied in full without reformatting, deduplication, rerun application or guessed counter repair. The fresh aggregate wrapper omits counts/time. Original wrapper attributes and outside-suite comments/declarations are retained in the evidence/original files, rather than inherited. Qualified wrapper attributes that could change descendants refuse.
  • Failure/error/skipped and selected rerun/flaky evidence remain literal. Source counters may disagree with observed testcase nodes or outcomes; the merger preserves that evidence and does not infer a unique test identity, executed count, success rate or sequential wall time. No passing-test or CI compatibility certification is provided.
  • XML is parsed in a detached native document and is never inserted into the app DOM. A bounded locator checks quotes/comments/CDATA before parsing; it is not treated as an XML validator. Native XML parsing is synchronous and is bounded by input/tag limits, not a promised interruptible CPU timer.
  • Combined local reads have a 5-second deadline. One same-origin module Worker prepares the existing ZIP writer within 10 seconds, then has a separate 2-second computation deadline. Pagehide cancels waiting and prevents a late read from starting a Worker; an underlying browser File read is not claimed abortable. Workers terminate after settlement, deadline or pagehide.
  • Merged XML is at most 2,200,000 UTF-8 bytes; complete evidence at most 4 MiB and the stored ZIP at most 10 MiB. Rechecking the aggregate reserves one added wrapper level/element and at most 202 wrapper and spacing nodes. These bounds are not a guaranteed phone heap or responsiveness claim.
  • The ZIP contains complete original reports and logs, which may contain private information. It is a source-preserving report artifact, not a sanitizer. No input is executed, uploaded, fetched, automatically saved or sent to a CI service.

Common questions

Why does the merged wrapper have no total time?

Report durations may include different setup/teardown conventions or parallel runs. Adding them would not establish a shared elapsed wall time. Original suite and testcase values remain unchanged.

Will cases with the same name replace each other?

No. Every source occurrence is copied in selection order. Source ordinals and original testcase attributes remain in the evidence so your own consumer can interpret repeated runs.

Does this support every JUnit XML producer?

No. Legacy XML is a de facto family. This tool accepts a documented flat, namespace-free profile and refuses unsupported structures atomically. Verify the artifact with your intended report publisher.

Keep going with related tools

All developer →