flutter-ci

这是一个CI工具,用于分析拉取请求的覆盖率,忽略PR中未更改的行。

动机

CI工具中的覆盖率阈值是鼓励开发人员编写测试并不断提高整个项目质量的常用方法。不幸的是,通过分析整个项目的覆盖率来判断拉取请求的覆盖率并不总是公平的,尤其是在大型重构任务中,这些任务可能会自然降低覆盖率。

此软件包尝试采用一种不同的方法来分析测试覆盖率。我们只分析在拉取请求中添加的行。覆盖率将通过未覆盖的新行数除以新行数来计算。

您可以设置阈值,使CI工具中的测试失败。此软件包还可以打印出未覆盖的行,从而更容易识别缺失的测试。

安装

将此行添加到您的package的pubspec.yaml的dev_dependencies部分

dev_dependencies:
  pull_request_coverage:

您应该指定版本以避免破坏性更改

用法

此软件包使用两个信息来生成其报告

  • 一个lcov.info文件,由flutter test --coverage命令生成
  • 当前分支与主分支之间的差异,由git diff命令生成

生成lcov.info文件

flutter test --coverage命令存在一个已知问题。它可能不会报告未测试的文件。对此有一个变通方法,在此问题中进行了描述

运行以下命令生成coverage/lcov.info文件

flutter test --coverage

运行pull_request_coverage

为了检查PR的代码,此包需要其分支与存储库的目标分支之间的差异。此差异从STDIN输入读取。

您可以使用bash的|运算符将STDIN馈送,如下所示

git diff repository/main | flutter pub run pull_request_coverage

输出示例

lib/screen/fantasy_button.dart is fully covered ? (+10)
lib/screen/fantasy_list.dart has uncovered lines ?  (+133)
 58 : +      );
 59 : +    }
 60 : +: +    return Scrollbar(
 ⬤  : +      child: AzListView(
 ⬤  : +        data: fantasyItems,
 64 : +        indexBarAlignment: Alignment.centerLeft,
 ⬤  : +        itemCount: fantasyItems.length,
 66 : +        indexBarHeight: double.infinity,
 67 : +        indexBarOptions: const IndexBarOptions(
 68 : +          hapticFeedback: true,
 72 : +            fontWeight: FontWeight.w500,
 73 : +          ),
 74 : +        ),
 ⬤  : +        itemBuilder: _buildTile,
 76 : +      ),
 77 :      );
 78 :    }
After ignoring excluded files, this pull request has:256 new lines, 5 of them are NOT covered by tests. But....it's enough to pass the test ?
    ✪ 98.046875% of coverage. This is above the limit of 95.0%

符号标记的行是未覆盖的行。

设置阈值且不显示未覆盖行的示例

git diff repository/main | flutter pub run pull_request_coverage --minimum-coverage 95 --maximum-uncovered-lines 5 --hide-uncovered-lines

退出码

代码 描述
0 测试通过。
1 测试失败(仅当设置了阈值时)。
255 执行失败且测试未执行。

选项

参数 默认值 必需 描述
lcov-file coverage/lcov.info no lcov文件路径
exclude-suffix .g.dart,.pb.dart,.pbenum.dart,.pbserver.dart,.pbjson.dart no 排除所有以这些后缀开头的文件路径,用逗号分隔
exclude-prefix no 排除所有以这些前缀开头的文件路径,用逗号分隔
minimum-coverage no 如果覆盖率未达到此最低值,则测试失败
maximum-uncovered-lines no 如果未覆盖行的总数小于此值,则测试失败
标志 描述
hide-uncovered-lines 不打印未被测试覆盖的源代码

GitHub

查看 Github