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)提供三个层面的度量:

  1. 总体通过率:pass / (pass + failed),排除 notExecuted 和 ignored。
  2. 模块级通过率:每个 Module 独立计算,用于确定模块是否通过兼容性认证。
  3. 用例级详细表格:包含 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 流程图)

CTS测试结果解析工作流 原始结果集合 test_result.xml / logs test_result.xml 层级提取 + 结果过滤 failures报告 失败用例平铺列表 看板摘要 summary.html 度量计算 必测/可选测区分 plan属性 / 模块标记 最终测试报告 通过率 / 必测失败列表 说明: 必测项过滤是认证准出的核心步骤;failures报告中的非断言失败(如timeout)需结合设备日志二次确认。

4.8 实践建议:自动化解析 + 看板集成

在生产环境中,推荐将解析流程嵌入持续集成流水线:

  1. 使用 ctstestresultparser 工具(AOSP 源码中 tools/tradefederation/ 目录下)批量转换 test_result.xml 为 JSON 结构。
  2. 结合 Plan 文件的 optional 标志自动标记模块类型。
  3. 将看板摘要数据推送至看板系统(如 Grafana、ELK),实时监控必测项通过率变化。
  4. 设置告警:当必测项失败数 >0 或有 timeout/notExecuted 时触发人工 review。
关键命令:ctstestresultparser --input test_result.xml --output parsed_results.json --plan cts/plans/cts.xml