-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
Problem
junit-upload rejects JUnit XML files that have <testsuite> as the root element — it only accepts <testsuites> as root.
Many test runners produce per-class/per-suite files with <testsuite> as root (no <testsuites> wrapper). Users are forced to merge files with a tool like junit-merge before uploading.
Error
[
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": ["testsuites"],
"message": "Required"
}
]
Producers that output bare <testsuite> root
- TestNG
JUnitReportReporter— one file per class, each with<testsuite>root - Maven Surefire native reports —
TEST-*.xmlfiles with<testsuite>root - Many JUnit 4/5 runners — per-class XML files
Example file that fails
<?xml version="1.0" encoding="UTF-8"?>
<testsuite hostname="host" failures="0" tests="4" name="com.example.MathUtilsTest"
time="0.001" errors="0" timestamp="2026-02-10T12:24:12 UTC" skipped="0">
<testcase classname="com.example.MathUtilsTest" name="testAddition" time="0.001"/>
<testcase classname="com.example.MathUtilsTest" name="testDivisionByZero" time="0.000"/>
</testsuite>Expected behavior
When the root element is <testsuite>, treat it as if it were wrapped in <testsuites> — i.e. a single-suite file.
Suggested fix
In junitXmlParser.ts, after xml2js parsing, normalize the structure:
const xmlData = await xml.parseStringPromise(xmlString, { ... })
// Accept bare <testsuite> as root by wrapping it
if (xmlData.testsuite && !xmlData.testsuites) {
xmlData.testsuites = { testsuite: [xmlData.testsuite] }
delete xmlData.testsuite
}This would eliminate the need for junit-merge when uploading multiple per-class files:
# Currently requires merge step:
npx junit-merge -o merged.xml -d target/surefire-reports/junitreports
qasphere junit-upload merged.xml
# With this fix, just pass all files directly:
qasphere junit-upload target/surefire-reports/junitreports/*.xmlRelated
- junit-upload fails on <testsuites> without attributes #52 —
<testsuites>without attributes also fails
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels