#proc-macro-attributes #proptest #testing-macro #macro-attr #u32

macro proptest-attr-macro

Procedural attribute macro for writing proptest tests

3 releases (1 stable)

1.0.0 Oct 27, 2020
0.1.0 Jul 21, 2019

#1552 in Procedural macros

Download history 189/week @ 2025-10-08 190/week @ 2025-10-15 319/week @ 2025-10-22 322/week @ 2025-10-29 187/week @ 2025-11-05 1243/week @ 2025-11-12 430/week @ 2025-11-19 55/week @ 2025-11-26 81/week @ 2025-12-03 82/week @ 2025-12-10 125/week @ 2025-12-17 56/week @ 2025-12-24 37/week @ 2025-12-31 36/week @ 2026-01-07 34/week @ 2026-01-14 47/week @ 2026-01-21

155 downloads per month
Used in 5 crates (4 directly)

Apache-2.0

11KB
100 lines

This crate provides a procedural attribute macro version of proptest's proptest! macro.

So instead of having to write:

use proptest::proptest;

proptest! {
    fn test_excluded_middle(x: u32, y: u32) {
        assert!(x == y || x != y);
    }
}

you can write:

use proptest_attr_macro::proptest;

#[proptest]
fn test_excluded_middle(x: u32, y: u32) {
    assert!(x == y || x != y);
}

Limitations

Procedural attribute macros can only be used with valid Rust syntax, which means that you can't use proptest's in operator (which allows you to draw values from a specific strategy function):

// This won't compile!
#[proptest]
fn test_even_numbers(x in even(any::<u32>())) {
    assert!((x % 2) == 0);
}

Instead you must provide an actual parameter list, just like you would with a real Rust function definition. That, in turn, means that your function parameters can only draw values using the any strategy for their types. If you want to use a custom strategy, you must create a separately named type, and have the new type's Arbitrary impl use that strategy:

struct Even { value: i32 }

impl Arbitrary for Even {
    type Parameters = ();
    type Strategy = BoxedStrategy<Even>;

    fn arbitrary_with(_args: ()) -> Self::Strategy {
        (0..100).prop_map(|x| Even { value: x * 2 }).boxed()
    }
}

#[proptest]
fn test_even_numbers(even: Even) {
    assert!((even.value % 2) == 0);
}

Benefits

The main one is purely aesthetic: since you're applying the proptest attribute macro to valid Rust functions, rustfmt works on them!

Dependencies

~1.5MB
~39K SLoC