- everything is built around the concept of a
Strategy - a
Strategycan be a collection of other strategies, or a singleStrategy - a
Strategyreturns aValueTreethat 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_CASESis equal to256anyfor built in typesany::<u32>()is aStrategyfor allu32s
- we can use
prop_mapto transform strategies- eg a function expects to parse strings as integers
- the
Strategyshould 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_mapcreates 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 enumsJustfor enums without interior valuesStrategy+prop_mapfor enums with interior valuesproptestwill 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_mapcombinator for strategies that are generated by other strategies- Higher-Order Strategies
prop_flat_mapreturns 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_derivecan be used to automate implementingArbitraryfor simple casespropteststores the seed that was used to produce failing test cases
Notes
forkandtimeout- 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)