35 个版本 (18 个稳定版)
1.3.2 | 2023年10月30日 |
---|---|
1.3.0 | 2023年3月13日 |
1.2.0 | 2022年10月20日 |
1.1.3 | 2022年6月23日 |
0.1.0 | 2017年5月8日 |
#6 在 测试 中排名
每月下载量 1,440,141
在 1,289 个crate中使用 (416 个直接使用)
93KB
1.5K SLoC
Arbitrary
将任意非结构化输入生成结构化数据的特剧行为
关于
Arbitrary
crate 允许你构造任意类型的实例。
此crate主要旨在与类似 libFuzzer 和 cargo-fuzz
或 AFL 的fuzzer结合使用,帮助你将它们生成的原始、无类型的字节缓冲区转换为有类型、有效、结构化的值。这允许你将结构化测试用例生成与覆盖率指导、基于变异的fuzzer结合起来。
文档
示例
假设你正在编写一个颜色转换库,你有一个 Rgb
结构体来表示RGB颜色。你可能想为 Rgb
实现 Arbitrary
,这样你就可以在测试函数中获取任意的 Rgb
实例,并断言某些属性(例如,断言RGB转换为HSL后再转换回RGB总是回到起点)。
自动推导 Arbitrary
自动推导 Arbitrary
特性是实现 Arbitrary
的推荐方式。
自动推导 Arbitrary
需要你启用 "derive"
cargo功能
# Cargo.toml
[dependencies]
arbitrary = { version = "1", features = ["derive"] }
然后你可以简单地给你的类型添加 #[derive(Arbitrary)]
注释
// rgb.rs
use arbitrary::Arbitrary;
#[derive(Arbitrary)]
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
自定义单个字段
如果您的结构使用了一种不实现 Arbitrary
的类型,或者您希望对特定字段进行更多自定义,这将特别有用。
#[derive(Arbitrary)]
pub struct Rgba {
// set `r` to Default::default()
#[arbitrary(default)]
pub r: u8,
// set `g` to 255
#[arbitrary(value = 255)]
pub g: u8,
// Generate `b` with a custom function of type
//
// fn(&mut Unstructured) -> arbitrary::Result<T>
//
// where `T` is the field's type.
#[arbitrary(with = arbitrary_b)]
pub b: u8,
// Generate `a` with a custom closure (shortuct to avoid a custom function)
#[arbitrary(with = |u: &mut Unstructured| u.int_in_range(0..=64))]
pub a: u8,
}
fn arbitrary_b(u: &mut Unstructured) -> arbitrary::Result<u8> {
u.int_in_range(64..=128)
}
手动实现 Arbitrary
或者,您也可以手动编写一个 Arbitrary
的实现。
// rgb.rs
use arbitrary::{Arbitrary, Result, Unstructured};
#[derive(Copy, Clone, Debug)]
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl<'a> Arbitrary<'a> for Rgb {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let r = u8::arbitrary(u)?;
let g = u8::arbitrary(u)?;
let b = u8::arbitrary(u)?;
Ok(Rgb { r, g, b })
}
}
许可
根据您的选择,在 MIT 或 Apache-2.0 许可下授权。
除非您明确声明,否则,根据 Apache-2.0 许可定义,您提交给本项目并有意包含在内的任何贡献,将按照上述方式双重授权,不附加任何额外条款或条件。
依赖项
~105KB