覆盖率跑了三轮还是不累加:DevEco Studio 26.0 增量覆盖率怎么防止构建身份混用
DevEco Studio 26.0 Release 新增 Instrument、Local 和黑盒测试的增量覆盖率统计。增量并不等于把任意三份报告相加:源码、构建、插桩模式、过滤规则或用例集合改变后,旧数据可能已经不可比。看见百分比上升,不代表新代码真的被执行;看见不累加,也可能是构建身份或源码映射变了。
现场时间线:先把“偶发”变成可重复
固定一份带签名测试构建,按登录、收藏、离线恢复三组用例分三轮执行;记录 buildDigest、sourceDigest、coverageMode、obfuscation、include/exclude、testFilter、caseCount、reportId 和 coveredLineIds。第四轮只修改一行源码但沿用旧报告,验证门禁是否拒绝合并。覆盖率测试不支持开启混淆,文件命名和过滤规则也要按官方约束检查。
按首次正常、状态累积、故障出现、恢复操作四个节点记录输入和读回结果。只有时间线完整,才能区分是本轮操作、历史状态还是工具采样改变了现场。
证据链上的三个断点
增量合并的主键不是日期,而是构建身份
相同 buildDigest、sourceDigest 和插桩模式才能共享行号空间。源码改变后即使文件名相同,旧 lineId 也可能指向另一段代码。
这里必须同时保存输入条件、设备或窗口形态、触发动作和最终可观察状态。工具报告用于缩小范围,任务是否可完成仍由同一条用户路径的读回结果决定。
测试过滤条件决定分母和证据范围
level、size、testType 或目录过滤改变后,执行集合不同。报告必须保存实际用例数和 notRun,不能只抄最终百分比。
这里必须同时保存输入条件、设备或窗口形态、触发动作和最终可观察状态。工具报告用于缩小范围,任务是否可完成仍由同一条用户路径的读回结果决定。
覆盖率是执行证据,不是正确性证据
一行被命中只说明执行过。业务断言、失败用例和覆盖差异要并列展示,避免用高覆盖率掩盖弱断言。
这里必须同时保存输入条件、设备或窗口形态、触发动作和最终可观察状态。工具报告用于缩小范围,任务是否可完成仍由同一条用户路径的读回结果决定。
案例一:三轮构建相同,覆盖集合正确累加
每轮只跑一组用例,build/source/filter 完全一致。最终取 coveredLineIds 的并集,同时保留每轮失败数,能解释新增覆盖来自哪组用例。
修复后用原始条件再次执行完整任务,并保留修改前后同一节点的可见性、可操作性和状态对照。
案例二:修改源码后继续并入旧报告
sourceDigest 改变,行号空间失效。创建新基线并把旧报告归档为历史趋势,不把两者合成一个 90% 数字。
第二个案例选择不同形态或不同状态,用来证明方案不是对单一截图的局部修补。
工程侧模型
type CoverageRun={build:string;source:string;mode:string;filter:string;lines:number[]} function mergeable(a:CoverageRun,b:CoverageRun){return a.build===b.build&&a.source===b.source&&a.mode===b.mode&&a.filter===b.filter}模型只表达稳定的决策边界,界面组件、窗口事件和工具结果通过适配器接入,避免把设备差异散落在每个页面。
可独立执行的状态断言
function merge(a){const key=x=>[x.build,x.source,x.mode,x.filter].join('|');if(new Set(a.map(key)).size!==1)throw new Error('覆盖率报告不可比');return [...new Set(a.flatMap(x=>x.lines))].sort((x,y)=>x-y)} const lines=merge([{build:'A',source:'S',mode:'instrument',filter:'all',lines:[1,2]},{build:'A',source:'S',mode:'instrument',filter:'all',lines:[2,3]}]);if(lines.join(',')!=='1,2,3')throw new Error('覆盖行合并错误');这些断言验证纯状态、几何或边界计算,不代表 API 26 工程已经编译,也不代表真机、模拟器特定镜像或应用市场审核已经通过。
方案对比
| 方式 | 优点 | 风险 |
| 只看 IDE 最终百分比 | 最快 | 无法证明报告可比 |
| 每轮都全量重跑 | 简单可靠 | 大型项目反馈慢 |
| 身份一致时增量合并,变化时重建基线 | 效率与可信度兼顾 | 需要报告清单 |
我的选择:采用第三种,增量覆盖率必须先通过报告兼容性检查再合并。
封装与复用
封装 CoverageLedger,为每份报告附加构建、源码、模式、过滤条件、用例数和行集合;不兼容报告只做趋势对照,不参与同一百分比。
复用层输出决策和证据,不强行统一所有页面视觉。每个页面仍可保留自身信息层级,但必须满足相同的任务可达性与状态连续标准。
验收清单
- 覆盖测试关闭混淆。
- 保存 build 与 source 摘要。
- 记录实际过滤条件和 notRun。
- 源码变化后重建基线。
- 覆盖率与业务断言并列。
验证边界
本文依据当前华为官方文档整理能力与约束,纯状态模型已在本机执行。当前本机 HarmonyOS SDK 为 API 24,且没有连接 HDC 设备,因此 API 26 编译、目标模拟器镜像行为、折叠真机连续性和平台审核结果仍属于待验证项。完成目标环境验证后,应把版本、设备、构建身份和读回结果补入证据包。
官方资料
- DevEco Studio 26.0 增量覆盖率说明
- Instrument Test 与覆盖率统计
- HarmonyOS 开发者测试服务
- 工程目录与测试代码位置
最终结论
用构建摘要、覆盖模式、筛选条件和源码映射约束增量合并,避免把不可比报告拼成高覆盖率。 适配不是让截图“看起来差不多”,而是让关键任务在形态变化后依然可见、可操作、可恢复。