关于 dart-collect-coverage
dart-collect-coverage 是用于 Dart 和 Flutter 项目测试覆盖率收集与审查的技能,介绍自动和手动采集、LCOV 与 HTML 报告、忽略指令及 CI 覆盖率检查。
主要功能
- 01自动运行测试并收集覆盖率
- 02生成 LCOV 和 HTML 报告
- 03采集函数及分支覆盖率
- 04用忽略指令排除代码
- 05在 CI 中添加覆盖率检查
适用场景
- 01测量 Dart 项目的覆盖率
- 02生成 Flutter 测试报告
- 03检查函数或分支覆盖率
- 04设置 CI 覆盖率门槛
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill dart-collect-coverage安装后在 Claude Code 中输入/dart-collect-coverage确认已加载。
详细介绍
目录
设置
将 coverage 严格添加为 dev_dependency:
Dart 项目:
dart pub add dev:coverage
Flutter 项目:
flutter pub add dev:coverage
自动收集
使用捆绑的 test_with_coverage 脚本,一条命令即可收集覆盖率:
dart run coverage:test_with_coverage
该脚本会自动:
- 运行所有测试
- 从 Dart VM 收集 JSON 覆盖率数据
- 将数据格式化为
coverage/lcov.info中的 LCOV 报告
Monorepo 支持:明确指定测试目录:
dart run coverage:test_with_coverage -- pkgs/foo/test pkgs/bar/test
Flutter 专属覆盖率
生成 LCOV
flutter test --coverage
在项目根目录生成 coverage/lcov.info。
生成 HTML 报告
# Install lcov (macOS)
brew install lcov
# Generate HTML from LCOV
genhtml coverage/lcov.info -o coverage/html
# Open in browser
open coverage/html/index.html
过滤生成的代码
lcov --remove coverage/lcov.info \
'*.g.dart' \
'*.freezed.dart' \
'*.part.dart' \
-o coverage/lcov_cleaned.info
手动 VM 服务工作流
如需更精细地控制覆盖率收集(分支/函数级别):
1. 使用 VM 服务运行测试
dart run --pause-isolates-on-exit \
--disable-service-auth-codes \
--enable-vm-service=8181 \
test &
2. 收集原始覆盖率数据
dart run coverage:collect_coverage \
--wait-paused \
--uri=http://127.0.0.1:8181/ \
-o coverage/coverage.json \
--resume-isolates \
--function-coverage \
--branch-coverage
可选标志:
--function-coverage:函数级指标(Dart VM 2.17.0+)--branch-coverage:分支级指标(Dart VM 2.17.0+)
3. 格式化为 LCOV
dart run coverage:format_coverage \
--packages=.dart_tool/package_config.json \
--lcov \
-i coverage/coverage.json \
-o coverage/lcov.info \
--check-ignore
覆盖率忽略指令
使用内联注释,将特定代码排除在覆盖率指标之外。格式化时传入 --check-ignore 以强制执行。
| 指令 | 范围 | 用法 |
|---|---|---|
// coverage:ignore-line | 单行 | 不可达分支、平台检查 |
// coverage:ignore-start / // coverage:ignore-end | 代码块 | 生成的代码、旧版方法 |
// coverage:ignore-file | 整个文件 | 生成的文件、配置文件 |
// coverage:ignore-file
// This entire file is excluded from coverage
class GeneratedRoutes {
// coverage:ignore-start
void legacyInit() {
print('Deprecated initialization');
}
// coverage:ignore-end
bool isProduction(String env) {
if (env == 'prod') return true;
return false; // coverage:ignore-line
}
}
CI 集成
GitHub Actions 覆盖率门槛
- name: Run tests with coverage
run: flutter test --coverage
- name: Check coverage threshold
run: |
COVERAGE=$(lcov --summary coverage/lcov.info 2>&1 | grep "lines" | awk '{print $2}' | sed 's/%//')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage below 80% threshold!"
exit 1
fi
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: coverage/lcov.info
覆盖率目标(来自 AGENTS.md)
domain和bloc层的逻辑覆盖率达到 100%。- 覆盖所有主要 UI 组件的Widget。
- 对生成的代码(
.g.dart、.freezed.dart)使用// coverage:ignore-file。
工作流:生成覆盖率报告
任务进度
- 步骤 1:将
coverage添加到dev_dependencies。 - 步骤 2:运行
flutter test --coverage(或dart run coverage:test_with_coverage)。 - 步骤 3:确认
coverage/lcov.info文件存在。 - 步骤 4:过滤生成的代码:
lcov --remove ... '*.g.dart' '*.freezed.dart'。 - 步骤 5:生成 HTML:
genhtml coverage/lcov.info -o coverage/html。 - 步骤 6:检查未覆盖的文件:添加测试或使用
// coverage:ignore-file。 - 步骤 7:在 CI 流水线中添加覆盖率门槛(最低 80%)。
示例
pubspec.yaml 配置
name: my_app
environment:
sdk: ^3.0.0
dev_dependencies:
flutter_test:
sdk: flutter
coverage: ^1.15.0
bloc_test: ^9.1.0
mocktail: ^1.0.0
快速覆盖率检查脚本
#!/bin/bash
# scripts/coverage.sh
set -e
echo "Running tests with coverage..."
flutter test --coverage
echo "Filtering generated code..."
lcov --remove coverage/lcov.info \
'*.g.dart' '*.freezed.dart' '*.part.dart' \
-o coverage/lcov_cleaned.info
echo "Generating HTML report..."
genhtml coverage/lcov_cleaned.info -o coverage/html
echo "Opening report..."
open coverage/html/index.html
评论
支持 Markdown