JUnit执行单元测试后生成的XML测试报告是结构化的数据文件,主要用于记录测试用例的执行结果、耗时、错误信息等内容,方便后续工具解析和展示。常见的JUnit测试报告XML遵循特定的结构规范,不同版本的JUnit生成的报告格式略有差异,但核心结构基本一致。

JUnit测试报告XML整体结构
JUnit测试报告XML的根标签是<testsuite>,一个根标签对应一个测试套件的执行结果,根标签下可以包含多个<testcase>子标签,每个<testcase>对应一个测试用例的执行情况。如果测试套件下还有子套件,也可以嵌套<testsuite>标签。
根标签<testsuite>的核心属性
根标签<testsuite>包含描述整个测试套件执行情况的属性,具体属性含义如下:
| 属性名 | 含义 |
|---|---|
| name | 测试套件的名称 |
| tests | 测试套件中包含的测试用例总数量 |
| failures | 执行失败的测试用例数量 |
| errors | 执行过程中出现错误的测试用例数量 |
| skipped | 被跳过的测试用例数量 |
| time | 整个测试套件的执行总耗时,单位为秒 |
| timestamp | 测试执行的开始时间戳 |
子标签<testcase>的结构
每个<testcase>标签对应一个测试用例,包含该用例的基本信息和执行结果,核心属性如下:
- name:测试用例的方法名称
- classname:测试用例所在的类全路径
- time:该测试用例的执行耗时,单位为秒
如果测试用例执行成功,<testcase>标签内部没有其他子标签;如果执行失败或者出错,会包含<failure>或者<error>子标签;如果被跳过,会包含<skipped>子标签。
失败与错误标签的区别
<failure>标签用于表示测试用例的断言失败,即预期结果和实际结果不匹配,属性中包含失败的类型和具体信息,标签内部是失败的堆栈跟踪信息。<error>标签用于表示测试用例执行过程中抛出了未预期的异常,不是断言失败导致的问题。
完整的JUnit测试报告XML示例
以下是一个符合JUnit规范的测试报告XML示例,包含两个测试用例,其中一个执行成功,一个执行失败:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.example.demo.CalculatorTest" tests="2" failures="1" errors="0" skipped="0" time="0.125" timestamp="2024-05-20T10:30:00">
<testcase name="testAdd" classname="com.example.demo.CalculatorTest" time="0.05"/>
<testcase name="testSubtract" classname="com.example.demo.CalculatorTest" time="0.075">
<failure type="java.lang.AssertionError" message="预期结果为5,实际结果为3">
java.lang.AssertionError: 预期结果为5,实际结果为3
at org.junit.Assert.fail(Assert.java:89)
at org.junit.Assert.assertTrue(Assert.java:42)
at com.example.demo.CalculatorTest.testSubtract(CalculatorTest.java:25)
</failure>
</testcase>
</testsuite>
不同JUnit版本的格式差异
JUnit 4和JUnit 5生成的测试报告XML格式存在细微差别,JUnit 5生成的报告根标签可能会增加hostname属性记录执行主机名,同时<testcase>标签下可能支持更多的子标签来记录测试的输出信息。如果需要兼容不同版本的报告解析,建议在解析时先判断根标签的属性,再适配不同的结构。
报告解析注意事项
在解析JUnit测试报告XML时,需要注意特殊字符的转义问题,比如报告中的错误信息如果包含<、>等字符,会被转义为对应的实体字符,解析时需要先处理实体转义再使用内容。另外,部分CI工具生成的JUnit报告可能会添加自定义的命名空间,解析时需要忽略不认识的命名空间,只提取核心的标签和属性内容。