10 个版本 (5 个重大更改)

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.1.0 2023年2月18日

#247 in 测试

Download history 12/week @ 2024-03-27 23/week @ 2024-04-03

每月147次下载

Apache-2.0

18KB

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选项传递。

注意:在“已污染”的工作树上运行测试可能会引起问题。因此,建议仅在实际工作中使用fs-mtime,而在CI中使用此功能以快速告知开发者最可能受影响的测试结果。

git-diff-hunks

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

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

注意:在“已污染”的工作树上运行测试可能会引起问题。因此,建议仅在实际工作中使用fs-mtime,而在CI中使用此功能以快速告知开发者最可能受影响的测试结果。

依赖关系

~0.7–1.5MB
~34K SLoC