用途
该技能(skill)面向使用 Melos 管理多包 monorepo 的 Dart/Flutter 项目开发者,目标是通过系统性流程执行代码覆盖率工具、分析未被测试覆盖的代码路径,并编写有针对性的测试,将仓库覆盖率推向 100%。
主要能力
一、执行与聚合 monorepo 覆盖率
- 运行包测试并生成覆盖率:执行 monorepo 测试运行器,通过
melos run test在所有包上运行flutter test --coverage(或dart test --coverage)。 - 合并各包覆盖率文件:执行
melos run coverage,将各包级别的coverage/lcov.info合并为根目录下统一的lcov.info。据技能说明,聚合脚本scripts/combine_coverage.sh会动态将路径根重写为绝对路径,并删除临时包覆盖率目录以保持工作区整洁。 - 生成 HTML 覆盖率报告:使用
genhtml lcov.info -o coverage/html(genhtml 属于 lcov 工具集)将统一后的 lcov.info 转换为交互式 HTML 可视化报告。
二、定位未覆盖行(缺口分析)
无需浏览整个 HTML 报告,可在根 lcov.info 上运行以下 grep 与 awk 管道命令快速定位未测试行:
grep -E "SF:|DA:" lcov.info | awk -F: '/SF/ {file=$2} /DA/ {split($2,a,","); if(a[2]==0) print file, a[1]}'
输出会显示每个未覆盖语句的绝对文件路径与精确行号,例如:
/workspace/packages/preact_signals/lib/src/model.dart 21
/workspace/packages/preact_signals/lib/src/model.dart 25
三、达到 100% 覆盖率的测试策略
定位到未覆盖行后,可应用以下针对性测试策略编写有意义的测试:
- 模型与选项基础:确保值模型、选项与参数被完整执行。对
copyWith方法,需同时测试传入 null(断言回退到当前值)与显式值两种情况。对相等性(==)与 hashCode,需测试:比较相同引用(identical(this, other));比较属性相同的不同实例(期望相等);比较属性不同的不同实例(期望不相等);与 null 或完全不同类的实例比较。 - 复杂分支/条件逻辑:逐一检查每个嵌套的 if、else 与三元(? :)语句,构造使路径求值为 true 的测试输入,以及使路径求值为 false 的测试输入;确保边界检查、空集合与空安全回退被显式触发。
- 异常与捕获路径:为覆盖恢复逻辑或诊断断言,对 catch 块,可传入不兼容类型或构造导致运行时 TypeError 或 AssertionError 的场景以验证回退分支;对 dispose 与生命周期错误,先对 signal/primitive 调用
.dispose(),再尝试读写操作,断言其抛出SignalsReadAfterDisposeError或SignalsWriteAfterDisposeError。 - 深层递归集合:验证自定义深层集合断言(如列表、映射、集合或嵌套对象)在每一层级都能正确评估匹配与不匹配的配置。
四、清理与版本安全
在最终完成覆盖率最大化运行前,需检查仓库整洁性:
- 格式化测试文件:
dart format . - 运行 Lint 与静态分析:
melos run analyze - 保持 Git 状态干净:切勿将覆盖率文件(
lcov.info或coverage/)提交进 Git 历史。若被误暂存,用以下命令移除:
git rm -r --cached coverage/
git rm lcov.info
适用场景
适用于采用 Melos 协调多包测试的 Dart/Flutter monorepo 项目,尤其是需要以标准化流程收集、合并与可视化覆盖率数据,并系统性补齐测试缺口、追求高覆盖率的开发与持续集成场景。
限制
资料未提供该技能对不同项目结构、其他测试框架或非 Melos 工作流的适配说明;也未提供具体版本的兼容性要求、执行失败时的故障排查指引。执行相关命令前请确认本地环境已安装对应工具(如 lcov 工具集、Melos、Dart/Flutter SDK)。