#测试 #测试工具 #cargo #索引 #目录 #选择性 #difftests

nightly bin+lib cargo-difftests

Rust 项目的选择性回归测试工具

11 个版本 (6 个破坏性更新)

0.6.1 2024 年 2 月 24 日
0.6.0 2024 年 2 月 24 日
0.5.0 2024 年 2 月 3 日
0.4.0 2024 年 1 月 10 日
0.0.0 2023 年 2 月 9 日

#253 in Cargo 插件

Download history 26/week @ 2024-04-02

每月 169 次下载

Apache-2.0

175KB
3.5K SLoC

cargo-difftests

"疯狂就是一遍又一遍地做同样的事情,却期待不同的结果。"

—— 未知作者。

cargo-difftests 是一个针对 Rust 的选择性重新测试框架。简单来说,这是一个工具,它使用 LLVM 覆盖数据 + 一些关于自上次测试运行以来发生了什么变化的信息,以找到哪些测试最有可能受到这些变化的影响,因此需要重新运行。

基本假设是,如果一个测试在过去通过了,并且自测试运行以来没有更改执行测试的任何代码,则测试的结果不会改变。虽然有一些边缘情况,但对于大多数 crate 来说,这通常是正确的。

先决条件

cargo install cargo-generate # if you don't have it already

然后只需应用模板

cargo generate dnbln/cargo-difftests

用法

现在 cargo difftests 的简单用法如下(在模板仓库中)

% # collect profiling data
% cargo difftests collect-profiling-data
% touch src/advanced_arithmetic.rs # change mtime
% cargo difftests analyze --dir target/tmp/difftests/tests/test_add
clean
% cargo difftests analyze --dir target/tmp/difftests/tests/test_mul
dirty
% cargo difftests analyze --dir target/tmp/difftests/tests/test_div
dirty
% cargo difftests collect-profiling-data --filter test_mul --exact
% cargo difftests analyze --dir target/tmp/difftests/tests/test_mul
clean
% cargo difftests analyze --dir target/tmp/difftests/tests/test_div
dirty
% cargo difftests collect-profiling-data --filter test_div --exact
% cargo difftests analyze --dir target/tmp/difftests/tests/test_div
clean

如你所见,它相当详细,但有一个命令可以简化事情:rerun-dirty-from-index。这个命令接受一个存储了一些索引的目录,分析每个索引,然后重新运行被认为是脏的测试。

可能的流程如下

# initial profiling data collection
cargo difftests collect-profiling-data --compile-index --index-root=difftests-index-root --root=target/tmp/difftests
# modify some files
touch src/lib.rs
# analyze and rerun tests, then recompile indexes
CARGO_DIFFTESTS_EXTRA_ARGS='--compile-index,--index-root=difftests-index-root,--root=target/tmp/difftests' cargo difftests rerun-dirty-from-indexes --index-root=difftests-index-root

这将首先收集所有测试的配置文件数据,然后将一些索引编译到 difftests-index-root 目录中,然后在一些更改发生后,rerun-dirty-from-indexes 命令将重新运行脏测试,并从同一目录中的新数据中编译新的索引。

这是推荐的工作流程来使用 cargo-difftests。您可能想为这些命令创建一些别名,或将它们放入 shell 文件中,以便更容易使用。

cargo-difftests

所有测试运行完成后,需要解释分析配置文件,并检查包含已运行代码的文件自上次运行测试以来是否已修改。如果测试中使用的代码自上次运行以来已修改,则我们认为测试“不干净”,并应重新运行,以确保更改后仍通过测试。

所有这些分析都在这个包中完成。

简单来说,cargo-difftests会检查测试“影响”到的文件,即在执行过程中,给定文件中至少有一行代码被执行。如果这些文件中的任何一个已修改,则将其标记为“不干净”,并输出该结果。如果没有文件被修改,则重新运行测试可能不会改变结果,所以结果将是测试“干净”。

现在您可以运行测试,可能更改几个文件,然后运行以下命令

cargo difftests analyze-all --dir target/tmp/cargo-difftests # common ancestor of all the difftest directories passed to the testclient init function

这将输出一个JSON数组,包含有关测试的信息,以及是否需要重新运行("verdict": "dirty")。

特性

算法(--algo标志)

有多种方式可以判断文件更改是否会影响测试结果。

fs-mtime

最基本的方法是检查包含执行代码的文件的mtime,将其与测试运行时间进行比较。这在大多数情况下都很好用,并且是默认设置。

git-diff-files

基本上与上面相同,但假设上次完整测试运行是在最后一个提交时(适用于CI),然后我们比较最后一次提交和当前树状态之间的树,以检查哪些文件已更改。

还支持与指定的提交进行比较,而不是与最后一次提交进行比较,但需要通过--commit选项传递。

注意:在脏工作树上运行测试可能会导致问题。因此,建议仅在CI上使用此功能以快速告知开发者最可能受影响的测试结果,但在实际工作中,最好只使用fs-mtime

git-diff-hunks

此算法扩展了git-diff-files,但在这里,我们不是检查文件自上次提交以来是否被触及,而是检查文件中被修改的具体部分。这是因为git实际上为我们跟踪了单独的行。

同样,与git-diff-files类似,此算法也接受可选的--commit,用于与最后一次提交进行比较。

注意:在脏工作树上运行测试可能会导致问题。因此,建议仅在CI上使用此功能以快速告知开发者最可能受影响的测试结果,但在实际工作中,最好只使用fs-mtime

依赖项

~17–28MB
~503K SLoC