5个版本
0.1.4 | 2024年7月29日 |
---|---|
0.1.3 | 2024年6月27日 |
0.1.2 | 2024年6月24日 |
0.1.1 | 2024年5月29日 |
0.1.0 | 2024年5月29日 |
#259 in 测试
637 每月下载量
18KB
110 行
derive_fuzztest
这不是一个官方支持的Google产品。
描述
生成用于与cargo fuzz
一起使用的模糊目标的过程宏,以及用于与cargo test
一起使用的属性测试(通过quickcheck
或proptest
)。
两者都有的原因是因为属性测试允许快速迭代以确保测试工作正常,并可以在预提交CI中检查,而模糊测试可以更彻底地测试输入空间并持续运行。
示例
#![cfg_attr(fuzzing, no_main)]
#[derive_fuzztest::fuzztest]
fn transitive_ord(a: u32, b: u32, c: u32) {
if a >= b && b >= c {
assert!(a >= c);
}
if a <= b && b <= c {
assert!(a <= c);
}
}
#[test]
fn additional_test_here() {
/* ... */
}
结果报告
测试函数通过panic报告测试失败,类似于你编写常规#[test]
的方式。如果标记的测试函数在没有panic的情况下完成,则认为测试已通过。
在某些情况下,你可能想要丢弃一些输入,既不将其视为通过也不视为失败,只是继续测试另一个生成的输入。这可以通过从标记的函数中返回一个TestResult
来实现。属性测试框架将尝试生成更多测试用例来替换丢弃的一个,最多达到一定限制。对于模糊测试,丢弃的测试结果将不会添加到语料库中。
use derive_fuzztest::TestResult;
#[derive_fuzztest::fuzztest]
fn increment(a: u8) -> TestResult {
if a < u8::MAX {
assert_eq!(a + 1 - 1, a);
TestResult::Passed
} else {
TestResult::Discard
}
}
用法
运行生成的属性测试
cargo test
运行持续模糊测试
cargo install cargo-fuzz
cargo +nightly fuzz run <binary name>
包结构
如果你使用#[fuzz]
或#[fuzztest]
,模糊目标强制以下要求
- 目标必须位于一个单独的
[[bin]]
目标中,该目标只包含一个模糊测试目标。 - 包含 bin 目标的包中,
[package.metadata] cargo-fuzz = true
- bin 目标使用
#![cfg_attr(fuzzing, no_main)]
进行了标注
对于您的 foo
包,建议的结构是将测试放在 foo/fuzz/src/bin
下
foo
├── fuzz
│ ├── src
│ │ └── bin
│ │ └── fuzz_target_1.rs
│ └── Cargo.toml
├── src
│ └── [project source]
└── Cargo.toml
这与 cargo fuzz init
或 cargo fuzz add
生成的默认结构不同,这样我们可以利用 目标自动发现。如果您愿意,也可以使用 cargo fuzz
生成的默认结构,但请确保从 Cargo.toml
中的生成目标中删除 test = false
。
您还需要声明对 libfuzzer-sys
包的依赖,但仅当需要模糊测试时
[target.'cfg(fuzzing)'.dependencies]
libfuzzer-sys = "*"
(这种条件依赖的原因是 libfuzzer-sys
会将一个主函数注入到生成的二进制文件中,如果没有定义相应的 fuzz_target
,则会出现链接失败。)
功能
quickcheck
(默认)— 启用生成quickcheck
属性测试。proptest
— 启用生成proptest
属性测试。
相关阅读
依赖项
~0.7–2MB
~40K SLoC