CTS测试结果解析:test_result.xml、failures报告、看板摘要与必测/可选测项区分
4.1 测试结果文件体系概览
CTS执行完成后,系统会在输出目录(通常为android-cts/results/)下生成一组结构化文件。核心结果集包括:
- test_result.xml:逐模块、逐用例的完整执行结果,包含测试计划、模块名称、测试类、断言状态、堆栈摘要。
- failures 报告:文本或HTML格式的失败集合,通常由CTS测试框架自动抽取,用于快速定位故障。
- 看板摘要:
summary.html、testResult.html等聚合页面,给出通过率、失败率、未执行数等整体度量。 - 日志目录:host_log、device_log、bugreport等,辅助深度调试。
理解这些文件的内部组织和结构,是区分必测项与可选测项、精准回溯失败根因的前提。
4.2 test_result.xml 结构深度解析
test_result.xml 采用层级嵌套的 XML 格式,根节点为 <TestResult>,下含 <Build>、<Summary>、<Module> 等子元素。每个 <Module> 节点包含完整的 TestSuite、TestCase 和 Test 三级结构。
<TestResult>
<Build>
<BuildInfo name="android-cts" version="14_r1" />
<DeviceInfo serial="ABCDEF012345" />
</Build>
<Summary pass="5231" failed="17" notExecuted="8" />
<Module name="CtsNetTestCases">
<TestSuite name="android.net.cts">
<TestCase name="IpSecManagerTest">
<Test name="testIpSecTransform" result="pass" />
<Test name="testIpSecSecurityConfig" result="fail">
<Failure message="expected<true> but was<false>">
stackTrace line...
</Failure>
</Test>
</TestCase>
</TestSuite>
</Module>
</TestResult>
关键字段解析表
| 节点/属性 | 含义 | 取值示例 |
|---|---|---|
Module/@name | 模块名称,对应CTS计划中的子模块 | CtsNetTestCases |
TestCase/@name | 测试类名,通常为Java/Kotlin类 | IpSecManagerTest |
Test/@result | 单条用例执行结果 | pass / fail / notExecuted / timeout / ignored |
Failure/@message | 断言失败摘要 | expected<true> but was<false> |
Summary/@pass | 全量通过数 | 5231 |
Summary/@failed | 全量失败数 | 17 |
实践中推荐使用
lxml 或 xml.etree.ElementTree 批量解析 test_result.xml,提取 result="fail" 的 <Test> 节点及其祖先 Module 名称,用于自动化回归分析。4.3 failures 报告:聚合与定位
CTS 测试框架在运行结束后自动生成 test_failures_report.html 或 failures.txt,内容为所有失败用例的平铺列表,每个条目包含:
- 测试全限定名:
模块名#测试类名#方法名(如CtsNetTestCases#android.net.cts.IpSecManagerTest#testIpSecSecurityConfig) - 失败类型:
AssertionError、TimeoutException、TestRuntimeException等 - 失败消息:断言预期与实际值的对比
- 堆栈前10行:快速定位源码调用链
解析 failures 报告常用命令行工具组合:
# 提取所有失败用例的模块名(Linux)
grep -oP '\b(Cts\w+TestCases)' test_failures_report.html | sort -u
# 统计每个模块的失败数量
grep -c 'CtsNetTestCases' test_failures_report.html
# 使用 Python 解析 HTML 报告
from html.parser import HTMLParser
class FailParser(HTMLParser):
def handle_data(self, data):
if 'testResult="fail"' in self.get_starttag_text():
print(data)
失败报告中的
testResult="fail" 属性区分于 timeout 和 notExecuted,这三种状态在必测项中均需人为判定是否属于兼容性红线。可选测项的同类失败可酌情延期修复。4.4 看板摘要:度量指标与通过率计算
看板摘要文件(summary.html / testResult.html)提供三个层面的度量:
- 总体通过率:
pass / (pass + failed),排除 notExecuted 和 ignored。 - 模块级通过率:每个
Module独立计算,用于确定模块是否通过兼容性认证。 - 用例级详细表格:包含 testResult、duration、failure message 等。
CTS 认证的硬性门槛是:所有必测项(Must-pass Tests)通过率必须为100%,且无因设备兼容性引入的失败。可选测项(Optional Tests)的失败不影响认证通过,但需在提交材料中说明原因。
4.5 必测项与可选测项的区分方法
区分两种测试项的核心依据是 CTS 测试计划(Test Plan)与模块元数据。以下为三种权威区分方式:
| 区分方法 | 操作路径 | 示例 |
|---|---|---|
| 1. Test Plan 标记 | 查看 cts/plans/ 目录下的 .xml 计划文件,<Entry uri="..." optional="false"/> 表示必测;optional="true" 表示可选 | <Entry uri="CtsNetTestCases" optional="false"/> |
| 2. 模块属性查询 | 使用 run cts --list-modules 查看模块列表,输出中 [M] 代表必测,[O] 代表可选 | [M] CtsNetTestCases |
| 3. XML 解析验证 | 在 test_result.xml 的 <Module> 节点中检查 optional 属性,若缺失或 false 则为必测 | <Module name="CtsNetTestCases" optional="false"> |
# 使用 Python 从 test_result.xml 过滤必测模块中的失败用例
from xml.etree import ElementTree as ET
tree = ET.parse('test_result.xml')
root = tree.getroot()
must_fail = []
for module in root.findall('.//Module'):
is_optional = module.get('optional', 'false').lower() == 'true'
if is_optional:
continue
for test in module.findall('.//Test[@result="fail"]'):
class_name = test.getparent().get('name')
test_name = test.get('name')
must_fail.append((module.get('name'), class_name, test_name))
print("必测项失败列表:", must_fail)
注意:部分 CTS 版本中
optional 属性可能缺失,此时需回退到 Test Plan 文件或模块清单来决定。务必将 Test Plan 作为权威源,XML 属性仅作辅助。4.6 常见解析错误与调试指南
以下为解析结果文件时的常见问题及解决策略:
- XML 格式不完整:CTS 异常中断时 test_result.xml 可能未闭合,优先使用
lxml.etree.iterparse容错解析,或从cts-tradefed results --fetch-last重新获取。 - 模块名称与实际 APK 不匹配:检查
Module/@name是否包含版本号(如CtsNetTestCases_v7),需忽略版本后缀进行匹配。 - 失败报告中的行号偏移:AOSP 每次编译可能调整源码位置,应使用
symbols.zip中的 debug symbol 重映射行号。 - 看板摘要只显示 summary 不显示明细:确保
testResult.html与test_result.xml在同一目录,且浏览器未屏蔽本地 JavaScript。
4.7 结果解析工作流(单 SVG 流程图)
4.8 实践建议:自动化解析 + 看板集成
在生产环境中,推荐将解析流程嵌入持续集成流水线:
- 使用
ctstestresultparser工具(AOSP 源码中tools/tradefederation/目录下)批量转换 test_result.xml 为 JSON 结构。 - 结合 Plan 文件的
optional标志自动标记模块类型。 - 将看板摘要数据推送至看板系统(如 Grafana、ELK),实时监控必测项通过率变化。
- 设置告警:当必测项失败数 >0 或有 timeout/notExecuted 时触发人工 review。
关键命令:
ctstestresultparser --input test_result.xml --output parsed_results.json --plan cts/plans/cts.xml