Skip to content

Instantly share code, notes, and snippets.

@protortyp
Created January 12, 2025 22:12
Show Gist options
  • Save protortyp/05521817da483a7d1038b497a0e7e012 to your computer and use it in GitHub Desktop.
Save protortyp/05521817da483a7d1038b497a0e7e012 to your computer and use it in GitHub Desktop.

Proptest

  • everything is built around the concept of a Strategy
  • a Strategy can be a collection of other strategies, or a single Strategy
  • a Strategy returns a ValueTree 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 to 256
  • any for built in types
    • any::<u32>() is a Strategy for all u32s
  • we can use prop_map to transform strategies
    • eg a function expects to parse strings as integers
    • the Strategy should be a u32 range, then prop_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 struct
  • prop_oneof! to build enums
    • Just for enums without interior values
    • Strategy + prop_map for enums with interior values
    • proptest will shrink to items earlier int he prop_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 returns Err(TestCaseError::Reject)
    • a test with filter could theoretically run forever!
      • would run into Too many global rejects! error
  • 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
  • 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 implementing Arbitrary for simple cases
  • proptest stores the seed that was used to produce failing test cases

Notes

  • fork and timeout
    • 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment