Rust模糊测试宏库propfuzz-macro的使用,提升Rust代码覆盖率与漏洞检测的自动化测试工具

propfuzz-macro

propfuzz-macro 是 propfuzz 测试的 procedural macros 实现。

propfuzz-macro on crates.io Documentation (latest release) Documentation (trunk) License License

这个 crate 是 propfuzz 的一个实现细节,不应该直接使用。请通过 propfuzz 来使用它。

贡献

查看 CONTRIBUTING 文件了解如何参与贡献。

许可证

这个项目采用 Apache 2.0 许可证或 MIT 许可证。

安装

在你的项目目录中运行以下 Cargo 命令:

cargo add propfuzz-macro

或者在 Cargo.toml 中添加以下行:

propfuzz-macro = "0.0.1"

完整示例

以下是使用 propfuzz-macro 的完整示例代码:

// 首先需要添加 propfuzz 作为依赖
// Cargo.toml:
// [dev-dependencies]
// propfuzz = "0.0.1"

use propfuzz::prelude::*;

// 定义一个要测试的函数
fn add(a: i32, b: i32) -> i32 {
    a + b
}

// 使用 propfuzz 宏创建模糊测试
#[propfuzz]
fn test_add(#[propfuzz(values = "-100..100")] a: i32, #[propfuzz(values = "-100..100")] b: i32) {
    let result = add(a, b);
    assert_eq!(result, a + b);
}

// 主测试函数
#[test]
fn run_propfuzz_tests() {
    test_add(); // 这将运行模糊测试
}

这个示例展示了如何:

  1. 使用 #[propfuzz] 宏创建模糊测试
  2. 使用 #[propfuzz(values = "...")] 指定输入值的范围
  3. 对简单的加法函数进行模糊测试

注释说明:

  1. #[propfuzz] 宏会将函数转换为模糊测试
  2. values 参数指定了输入值的生成范围
  3. 测试函数不需要返回值,只需要包含断言

完整示例代码

// 在 Cargo.toml 中添加依赖
// [dev-dependencies]
// propfuzz = "0.0.1"

use propfuzz::prelude::*;

// 定义一个更复杂的函数进行测试
fn process_string(input: &str) -> usize {
    // 简单示例:返回字符串长度
    input.len()
}

// 定义字符串处理函数的模糊测试
#[propfuzz]
fn test_process_string(
    #[propfuzz(values = r#""a", "abc", "hello world", ""#)] input: &str
) {
    let result = process_string(input);
    assert_eq!(result, input.len());
}

// 定义另一个数值处理函数
fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

// 数值处理函数的模糊测试
#[propfuzz]
fn test_multiply(
    #[propfuzz(values = "-10..10")] a: i32,
    #[propfuzz(values = "-10..10")] b: i32
) {
    let result = multiply(a, b);
    assert_eq!(result, a * b);
}

// 主测试函数
#[test]
fn run_all_propfuzz_tests() {
    test_process_string();  // 运行字符串处理测试
    test_multiply();        // 运行乘法测试
}

这个完整示例展示了:

  1. 如何为不同类型的函数(字符串处理和数值计算)创建模糊测试
  2. 如何使用字符串字面量作为测试输入值
  3. 如何在一个测试函数中运行多个模糊测试
  4. 更复杂的测试场景和断言

注释说明:

  1. r#""a", "abc", "hello world", ""# 语法用于指定字符串测试用例
  2. 数值范围使用 -10..10 语法指定
  3. 每个模糊测试函数都可以独立运行
  4. 主测试函数集中运行所有模糊测试

1 回复

Rust模糊测试宏库propfuzz-macro使用指南

简介

propfuzz-macro是一个结合了属性测试(property-based testing)和模糊测试(fuzzing)的Rust宏库,旨在提升Rust代码的测试覆盖率和漏洞检测能力。它通过自动生成大量随机输入来测试代码的边界条件,帮助开发者发现潜在的错误和漏洞。

主要特性

  • 结合属性测试和模糊测试的优点
  • 通过宏简化测试编写
  • 自动生成随机输入数据
  • 支持测试用例缩小(minimization)以定位问题
  • 与Rust测试框架无缝集成

安装

在Cargo.toml中添加依赖:

[dependencies]
propfuzz-macro = "0.1"

完整示例demo

下面是一个完整的propfuzz-macro使用示例,演示了从基本测试到高级用法的完整流程:

// 1. 引入必要的宏和类型
use propfuzz_macro::{propfuzz, arbitrary, FuzzConfig};
use std::collections::HashMap;

// 2. 定义测试用的结构体
#[derive(Debug, Clone)]
struct User {
    id: u64,
    name: String,
    age: u8,
}

// 3. 自定义数据生成器
#[arbitrary]
fn gen_valid_user() -> User {
    User {
        id: propfuzz::any::<u64>(),
        name: format!("user_{}", propfuzz::any::<u16>()),
        age: (propfuzz::any::<u8>() % 100) + 1, // 年龄1-100岁
    }
}

// 4. 基本属性测试 - 测试加法交换律
#[propfuzz]
fn test_addition_commutative(a: i32, b: i32) {
    assert_eq!(a + b, b + a);
}

// 5. 带配置的模糊测试 - 测试字符串操作
#[propfuzz(FuzzConfig {
    cases: 500,
    max_size: 512,
    ..Default::default()
})]
fn test_string_concat(s1: String, s2: String) {
    let combined = s1.clone() + &s2;
    assert!(combined.starts_with(&s1));
    assert!(combined.ends_with(&s2));
}

// 6. 结构体测试 - 测试用户年龄验证
#[propfuzz]
fn test_user_age(user: User) {
    assert!(user.age >= 1 && user.age <= 100);
}

// 7. 使用自定义生成器的测试
#[propfuzz]
fn test_valid_user(#[from(gen_valid_user)] user: User) {
    assert!(!user.name.is_empty());
    assert!(user.name.starts_with("user_"));
}

// 8. 结合标准测试框架 - 测试HashMap操作
#[test]
#[propfuzz]
fn test_hashmap_operations(map: HashMap<String, i32>) {
    let keys: Vec<_> = map.keys().collect();
    let values: Vec<_> = map.values().collect();
    assert_eq!(keys.len(), values.len());
}

fn main() {
    println!("propfuzz-macro示例项目");
    println!("运行测试: cargo test");
}

最佳实践

  1. 从简单的属性开始测试,逐步增加复杂性
  2. 关注不变性(invariants)而非具体值
  3. 为失败用例添加种子(seed)以便重现
  4. 结合常规单元测试使用
  5. 对性能敏感代码设置合理的输入大小限制

故障排查

当测试失败时,propfuzz-macro会:

  1. 自动缩小失败用例到最小重现规模
  2. 显示导致失败的输入值
  3. 提供种子值以便重现问题

例如:

Test failed with smallest input: "a\0b"
Seed: 0x1234567890abcdef

性能考虑

  • 模糊测试可能比常规测试耗时更长
  • 对于大型项目,考虑在CI中并行运行测试
  • 使用FuzzConfig调整测试用例数量和大小

propfuzz-macro通过自动化生成测试用例和检测边界条件,可以显著提高代码质量和安全性,是Rust项目测试工具箱中的有力补充。

回到顶部