- everything is built around the concept of a
Strategy
- a
Strategy
can be a collection of other strategies, or a singleStrategy
- a
Strategy
returns aValueTree
that shrinks or complicates a value within that strategy- eg in a number range, shrinking would approx try to do a binary search to figure out the failing threshold
PROPTEST_CASES
is equal to256
any
for built in typesany::<u32>()
is aStrategy
for allu32
s
- we can use
prop_map
to transform strategies- eg a function expects to parse strings as integers
- the
Strategy
should be a u32 range, thenprop_map
-ped to a string fn test_do_stuff(v in any::<u32>().prop_map(|v| v.to_string())
prop_map
creates a new strategy which transforms every generated value with the provided function- the main way to generate new types
prop_compose!
to build structprop_oneof!
to build enumsJust
for enums without interior valuesStrategy
+prop_map
for enums with interior valuesproptest
will shrink to items earlier int heprop_oneof![...]
list!!- sort simplest to most complex!
- Filters
- Local: apply to a single strategy
- Global: apply to the whole test case, the whole case is regenerated if it doesn't fit the filter
- local:
prop_filter!
- global:
prop_assume!
, is called when the test case itself returnsErr(TestCaseError::Reject)
- a test with filter could theoretically run forever!
- would run into
Too many global rejects!
error
- would run into
prop_recursive!
for recursive types- first build non-recursive cases with
prop_oneof![...]
- then apply
prop_recursive!
on top of it to implement the recursive cases
- first build non-recursive cases with
prop_flat_map
combinator for strategies that are generated by other strategies- Higher-Order Strategies
prop_flat_map
returns a strategy- used when parameters depend on each other (eg vector and index)
prop_compose!
also comes in handy here, as it allows us to pass three argument lists (fn vec_and_idx()(...)(...) { ... })
proptest_derive
can be used to automate implementingArbitrary
for simple casesproptest
stores the seed that was used to produce failing test cases
Notes
fork
andtimeout
- allows to run test cases in subprocess and limit how long they can run
#![proptest_config(ProptestConfig { fork: true, timeout: 100, .. PropTestConfig::default()}]
- Performance (Link)