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 插件
每月 169 次下载
175KB
3.5K SLoC
cargo-difftests
"疯狂就是一遍又一遍地做同样的事情,却期待不同的结果。"
—— 未知作者。
cargo-difftests
是一个针对 Rust 的选择性重新测试框架。简单来说,这是一个工具,它使用 LLVM 覆盖数据 + 一些关于自上次测试运行以来发生了什么变化的信息,以找到哪些测试最有可能受到这些变化的影响,因此需要重新运行。
基本假设是,如果一个测试在过去通过了,并且自测试运行以来没有更改执行测试的任何代码,则测试的结果不会改变。虽然有一些边缘情况,但对于大多数 crate 来说,这通常是正确的。
先决条件
- Nightly rust。
cargo-binutils
推荐设置(使用 cargo-generate
)
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