โ Protest โ

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
Quick Start
Add Protest to your Cargo.toml:
[]
= { = "*", = ["derive", "persistence"] }
Optional Extensions:
= "*" # Extra generators (network, datetime, text)
= "*" # Stateful testing & model checking
= "*" # Property-based benchmarking
= "*" # Snapshot testing integration
= "*" # Migration helpers from proptest
See individual package READMEs for detailed documentation:
- protest-extras - Additional generators
- protest-stateful - Stateful testing
- protest-criterion - Benchmarking
- protest-insta - Snapshot testing
- protest-proptest-compat - Migration guide
- protest-cli - Command-line tool
Ultra-Simple Example
use *;
Ergonomic API Example
use *;
Attribute Macro Example
use property_test;
Custom Struct Example
use Generator;
API Styles
Protest offers multiple API styles - use what fits your needs:
1. Declarative Macros (Most Concise)
use *;
// Simple property test
property!;
// With configuration
property!;
// Assert style (panics on failure)
assert_property!;
2. Fluent Builder API (Most Flexible)
use *;
property
.iterations
.seed
.max_shrink_iterations
.run_with
.expect;
3. Attribute Macros (Most Integrated)
use property_test;
4. Direct API (Most Control)
use *;
;
let result = check;
assert!;
Common Property Patterns
Protest includes built-in helpers for common mathematical properties:
use *;
// Commutativity: f(a, b) == f(b, a)
commutative;
// Associativity: f(f(a, b), c) == f(a, f(b, c))
associative;
// Idempotence: f(f(x)) == f(x)
idempotent;
// Round-trip: decode(encode(x)) == x
round_trip;
// Inverse functions: f(g(x)) == x && g(f(x)) == x
inverse;
// Identity element: f(x, e) == x
has_identity;
// Monotonicity
monotonic_increasing;
// Distributivity
distributive;
Async Support
Full support for runtime-agnostic async property testing. Works with any async runtime (tokio, async-std, smol):
use *;
;
async
Note: Protest is runtime-agnostic - you bring your own async runtime. Add tokio, async-std, or smol to your dev-dependencies as needed.
Automatic Generator Inference
Protest automatically infers generators for common types:
use AutoGen;
// All primitive types
i32auto_generator;
Stringauto_generator;
boolauto_generator;
// Collections
Vec::auto_generator;
auto_generator;
// Tuples
<>auto_generator;
// Options
Option::auto_generator;
// Your custom types with #[derive(Generator)]
auto_generator;
Shrinking
When a property fails, Protest automatically finds the minimal counterexample:
property!;
// Fails with: Property failed with input 50 (shrunk from larger value)
// Focus on input: 50
Configuration
Extensive configuration options:
use *;
use Duration;
let config = TestConfig ;
Failure Persistence & Replay
Save failing test cases and automatically replay them (requires persistence feature):
use *;
new
.test_name
.persist_failures // Enable automatic failure saving & replay
.iterations
.run;
What happens:
- Failed tests are automatically saved to
.protest/failures/ - On subsequent runs, failures are replayed before running new cases
- Fixed failures are automatically cleaned up
Install the CLI tool for advanced failure management:
See the CLI documentation for complete details on managing failures, generating regression tests, and corpus building.
Stateful Property Testing
Test state machines, databases, and concurrent systems with protest-stateful:
use ;
Features:
- State machine testing with derive macros
- Model-based testing (compare against reference implementation)
- Temporal properties (Always, Eventually)
- Linearizability verification for concurrent systems
See protest-stateful README for complete documentation.
Examples
The repository includes comprehensive examples:
basic_usage.rs- Getting startedergonomic_api_demo.rs- All ergonomic featurescustom_structs.rs- Custom types with deriveasync_properties.rs- Async testingadvanced_patterns.rs- Advanced techniques
Run examples:
Property-Based Benchmarking
Benchmark with diverse generated inputs using protest-criterion:
use Criterion;
use PropertyBencher;
See protest-criterion README for details.
Property-Based Snapshot Testing
Visual regression testing with protest-insta:
use PropertySnapshots;
See protest-insta README for details.
Migrating from Proptest
Use protest-proptest-compat for migration helpers:
Before (Proptest)
proptest!
After (Protest)
See protest-proptest-compat README for the complete migration guide.
Feature Flags
[]
= ["derive"]
= ["protest-derive"] # Derive macros for Generator trait
= ["serde", "serde_json"] # Failure persistence & replay
Protest has minimal dependencies and no required runtime dependencies. Async support is built-in and runtime-agnostic. The persistence feature is optional and adds serde for JSON serialization of test failures.
Comparison with Other Libraries
| Feature | Protest | proptest | quickcheck |
|---|---|---|---|
| Ergonomic API | โ | โ | โ |
| Automatic Inference | โ | โ | Partial |
| Derive Macros | โ | โ | โ |
| Async Support | โ | โ | โ |
| Declarative Macros | โ | โ | โ |
| Fluent Builders | โ | Partial | โ |
| Pattern Helpers | โ | โ | โ |
| Shrinking | โ | โ | โ |
| Statistics | โ | Partial | โ |
| Failure Persistence | โ | Partial | โ |
| Test Corpus | โ | โ | โ |
Documentation
Full documentation is available on docs.rs.
Key Modules
protest::ergonomic- Ergonomic API (closures, builders, patterns)protest::primitives- Built-in generators (int, string, vec, hashmap, etc.)protest::generator- Generator trait and utilitiesprotest::property- Property trait and executionprotest::shrink- Shrinking infrastructureprotest::persistence- Failure persistence and replay (optional)protest::config- Configuration typesprotest::statistics- Coverage and statistics
Protest Extras
The protest-extras crate provides 23 additional specialized generators and enhanced shrinking strategies:
See the protest-extras README for detailed examples and documentation.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Inspired by:
- proptest - Rust property testing
- QuickCheck - Original Rust QuickCheck
- Hypothesis - Python property testing
Made with โค๏ธ for the Rust community