SonarQube扫描Node.js项目时报未知XML节点错误如何解决
问题根因
当前报错是因为sonar.testExecutionReportPaths参数要求读取Sonar自定义的通用测试执行XML格式,而你通过Mocha xunit reporter输出的是标准JUnit/xunit格式XML,根节点为<testsuite>,不符合前者要求的<testExecutions>根节点规则,因此解析失败。
解决方案
方案1(推荐:无需转换格式,仅改配置即可)
Sonar原生支持JUnit/xunit格式的测试报告,直接修改你的Sonar项目配置即可:
将原有配置中的
sonar.testExecutionReportPaths = unit_test_results.xml
替换为:
sonar.junit.reportPaths = unit_test_results.xml
修改完成后重新执行扫描即可,无需调整测试脚本,也不需要做XML格式转换。
方案2(需格式转换场景)
如果你的使用场景要求必须使用sonar.testExecutionReportPaths参数,可以通过自定义脚本实现格式转换,Node.js环境下可借助xml2js库完成,参考实现代码如下:
const fs = require('fs'); const xml2js = require('xml2js'); const parser = new xml2js.Parser(); const builder = new xml2js.Builder(); // 读取源xunit格式测试报告 fs.readFile('unit_test_results.xml', (err, data) => { if (err) throw err; parser.parseString(data, (err, result) => { if (err) throw err; const testCases = result.testsuite.testcase; const sonarReport = { testExecutions: { $: { version: "1" }, file: [] } }; // 按用例所属文件分组 const fileGroup = {}; testCases.forEach(tc => { const classname = tc.$.classname; if (!fileGroup[classname]) { fileGroup[classname] = { $: { path: classname }, // 可根据实际业务规则替换为真实文件路径 testCase: [] }; } fileGroup[classname].testCase.push({ $: { name: tc.$.name, duration: Math.round(Number(tc.$.time) * 1000) // Sonar要求duration单位为毫秒,原单位为秒需转换 } }); }); sonarReport.testExecutions.file = Object.values(fileGroup); // 输出转换后的Sonar通用格式报告 const outputXml = builder.buildObject(sonarReport); fs.writeFileSync('sonar_test_report.xml', outputXml); }); });
转换完成后将Sonar配置修改为:
sonar.testExecutionReportPaths = sonar_test_report.xml
重新执行扫描即可。
内容的提问来源于stack exchange,提问作者Lucifer007
相关产品推荐
相关产品推荐

