Preview
Open Original
I wrote a library for property based testing in rust. Iโll post part of the readme here for ease
Property-Based Testing for Rust - An ergonomic, powerful, and feature-rich property testing library with minimal boilerplate.
Features
๐ Ergonomic API - Test properties with closures, no boilerplate
๐ฏ Automatic Generator Inference - Smart type-based generator selection
๐ง Derive Macros - #[derive(Generator)] for custom types
๐ฆ Declarative Macros - property!, assert_property!, generator!
โก Async Support - First-class async property testing
๐ Smart Shrinking - Automatic minimal counterexample finding
๐พ Failure Persistence - Save and replay failing test cases (optional)
๐ง CLI Tool - Manage failures from the command line ...
I wrote a library for property based testing in rust. Iโll post part of the readme here for ease
Property-Based Testing for Rust - An ergonomic, powerful, and feature-rich property testing library with minimal boilerplate.
Features
๐ Ergonomic API - Test properties with closures, no boilerplate
๐ฏ Automatic Generator Inference - Smart type-based generator selection
๐ง Derive Macros - #[derive(Generator)] for custom types
๐ฆ Declarative Macros - property!, assert_property!, generator!
โก Async Support - First-class async property testing
๐ Smart Shrinking - Automatic minimal counterexample finding
๐พ Failure Persistence - Save and replay failing test cases (optional)
๐ง CLI Tool - Manage failures from the command line (protest-cli)
๐จ Fluent Builders - Chain configuration methods naturally
๐งช Common Patterns - Built-in helpers for mathematical properties
๐ Parallel Execution - Run tests in parallel for speed
๐ Statistics & Coverage - Track generation and test coverage
๐ญ Flexible - Works with any type, sync or async
Ultra-Simple Example
use protest::*;
#[test]
fn test_addition_commutative() {
// Test that addition is commutative with just one line!
property!(generator!(i32, -100, 100), |(a, b)| a + b == b + a);
}
Ergonomic API Example
use protest::ergonomic::*;
#[test]
fn test_reverse_twice_is_identity() {
property(|mut v: Vec<i32>| {
let original = v.clone();
v.reverse();
v.reverse();
v == original
})
.iterations(1000)
.run_with(VecGenerator::new(IntGenerator::new(-50, 50), 0, 100))
.expect("Property should hold");
}
Attribute Macro Example
use protest::property_test;
#[property_test(iterations = 100)]
fn test_string_length(s: String) {
// Generator automatically inferred from type
assert!(s.len() >= 0);
}
Custom Struct Example
use protest::Generator;
#[derive(Debug, Clone, PartialEq, Generator)]
struct User {
#[generator(range = "1..1000")]
id: u32,
#[generator(length = "5..50")]
name: String,
age: u8,
active: bool,
}
#[property_test]
fn test_user_id(user: User) {
assert!(user.id > 0 && user.id < 1000);
}