mcpField
D
dart-collect-coverage

dart-collect-coverage

github.com/dhruvanbhalara测试与质量3050 次安装9 周前更新
代码仓库

关于 dart-collect-coverage

dart-collect-coverage 是用于 Dart 和 Flutter 项目测试覆盖率收集与审查的技能,介绍自动和手动采集、LCOV 与 HTML 报告、忽略指令及 CI 覆盖率检查。

主要功能

  1. 01自动运行测试并收集覆盖率
  2. 02生成 LCOV 和 HTML 报告
  3. 03采集函数及分支覆盖率
  4. 04用忽略指令排除代码
  5. 05在 CI 中添加覆盖率检查

适用场景

  1. 01测量 Dart 项目的覆盖率
  2. 02生成 Flutter 测试报告
  3. 03检查函数或分支覆盖率
  4. 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

该脚本会自动:

  1. 运行所有测试
  2. 从 Dart VM 收集 JSON 覆盖率数据
  3. 将数据格式化为 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