4 个版本 (2 个破坏性更新)
0.3.1 | 2024年3月23日 |
---|---|
0.3.0 | 2024年3月23日 |
0.2.0 | 2024年3月23日 |
0.1.0 | 2024年3月23日 |
#220 在 Cargo 插件
每月下载量 43 次
53KB
986 行
Cargo Darwin
cargo-darwin
是一个基于 cargo
工具的插件。
Darwin 会对你的代码进行变异,如果你的代码仍然通过检查测试,则说明你的代码测试不足。
安装
cargo install cargo-darwin
用法
cargo darwin /path/to/project/to/test
将显示类似以下内容
[Missing] : Tests pass, the mutation hasn't been caught, suspicion of missing test
[OK] : Tests failed, the mutation has been caught
[Timeout] : Mutation introduces infinite loop, inconclusive
[Killed] : Mutation introduces non buildable modification
---
[OK] : Mutation #0 replace - by + in function "sub" of file src\a\toto.rs at line 11:6
[OK] : Mutation #1 replace - by * in function "sub" of file src\a\toto.rs at line 11:6
[Killed] : Mutation #2 replace - by && in function "sub" of file src\a\toto.rs at line 11:6
[Missing] : Mutation #3 replace + by - in function "add" of file src\lib.rs at line 5:6
[Missing] : Mutation #4 replace + by * in function "add" of file src\lib.rs at line 5:6
[Missing] : Mutation #5 replace + by - in function "add" of file src\lib.rs at line 5:10
[Missing] : Mutation #6 replace + by * in function "add" of file src\lib.rs at line 5:10
存在一个 --dry-run
模式,只列出变异而不实际应用测试。
cargo darwin --dry-run /path/to/project/to/test
详细信息
Darwin 遍历提供的路径(如果没有提供,则获取当前目录)。对于每个以 .rs 扩展名结尾的文件,Darwin 会分析文件并尝试找到可变函数。如果一个函数没有任何 #[test]
或 #[tokio::test]
属性,则该函数是可变的。
fn mutable() {}
#[test]
fn non_mutable() {}
#[tokio::test]
async fn non_mutable_async() {}
该项目的开发非常早期,因此变异非常有限,实际上只是二进制表达式,如 a + b
或 a - b
。例如这个可变函数
fn add(x: u8, y:u8) -> u8 {
x + y
}
将变为
fn add(x: u8, y:u8) -> u8 {
x - y
}
然后 Darwin 创建实际项目的副本并在复制的文件上应用修改。一旦项目发生变异,Darwin 就会运行 cargo build
,如果项目编译成功,则变异是可持续的。如果是这样,Darwin 将运行 cargo test
,有以下三种可能情况
- 项目测试通过:项目的测试效率低下,因为变异没有被捕获
- 测试失败:项目至少有一个测试捕获了变异
- 超时:即使编译成功,也会引入循环或导致测试无限运行的突变
报告
所有报告都可以在“突变路径”下的“报告”文件夹中找到。例如,如果您运行了darwin,则会得到以下树
cargo darwin --mutation-path /tmp/darwin /path/to/project/to/test
...
tmp/
├─ darwin/
│ ├─ reports/
│ │ ├─ mutation_0.log
│ │ ├─ mutation_1.log
│ │ ├─ summary
│ ├─ 0/
│ ├─ 1/
突变项目
如果定义了--keep
标志,在测试后,您可以访问生成的项目。每个项目都有一个突变ID,相关的突变ID可以在摘要文件中找到
摘要
总结应用的突变以及每个突变的结果。
[OK] : Mutation #0 replace - by + in function "sub" of file src\a\toto.rs at line 11:6
[OK] : Mutation #1 replace - by * in function "sub" of file src\a\toto.rs at line 11:6
[Killed] : Mutation #2 replace - by && in function "sub" of file src\a\toto.rs at line 11:6
[Missing] : Mutation #3 replace + by - in function "add" of file src\lib.rs at line 5:6
[Missing] : Mutation #4 replace + by * in function "add" of file src\lib.rs at line 5:6
[Missing] : Mutation #5 replace + by - in function "add" of file src\lib.rs at line 5:10
[Missing] : Mutation #6 replace + by * in function "add" of file src\lib.rs at line 5:10
有关突变的更多信息,请检查相关的mutation_ID.log文件
突变报告
reports/mutation_X.log
文件是突变的详细视图。它们按照以下命名法构建
- 突变文件
- 突变
- 突变状态
- 突变差异
- 测试或构建输出。以下是一个输出示例
Mutation of file F:\Projets\Lab\Rust\darwin\playground\src\a\toto.rs
Mutation reason: replace - by *
Status : OK => Mutation Caught
Mutation diff:
@@ -8,7 +8,7 @@
//
fn sub(x: i8, y: i8) -> i8 {
let u = 8;
- x - y
+ x * y
}
Output:
#[test]
stderr:
Compiling playground v0.1.0 (F:\Projets\Lab\Rust\darwin\tmp\1)
Finished test [unoptimized + debuginfo] target(s) in 0.18s
Running unittests src\lib.rs (target\debug\deps\playground-29148ab9d23d3c5d.exe)
error: test failed, to rerun pass `--lib`
stdout:
running 2 tests
test a::toto::test_sub ... FAILED
test a::toto::async_test_sub ... FAILED
failures:
---- a::toto::test_sub stdout ----
thread 'a::toto::test_sub' panicked at src\a\toto.rs:16:5:
assertion `left == right` failed
left: 10
right: 3
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- a::toto::async_test_sub stdout ----
thread 'a::toto::async_test_sub' panicked at src\a\toto.rs:21:5:
assertion `left == right` failed
left: 10
right: 3
failures:
a::toto::async_test_sub
a::toto::test_sub
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
由于测试失败,突变被捕获,因此对于这个特定的突变,代码已经足够测试了
限制
该项目唯一的目的是理解突变测试及其实现方式。
这就是为什么到目前为止突变集是硬编码的。
并且非常有限
a + b
给出
a-b
a*b
a - b
给出
a+b
a*b
a&&b
趣闻
“Darwin”代表“自然选择定律”,生命通过突变适应环境,因此在进行cargo-darwin时,突变是不希望的。
我想称它为“Malcom”,以纪念《侏罗纪公园》中的“Ian Malcom”,但这个参考太牵强了^^‘
依赖项
~14–24MB
~413K SLoC