Desgin of property-based testing lib from functional programming in Scala
Basic idea:
-
Framework generates values and run propery checks against those values to ensure property is satisfied
-
Programmer comes up with algebraic properties of the API to be tested
-
Framework should be able to minimize failed test and generate exhaustive values for the properties space
Design process:
-
Obviously, we need a Gen[A] to represent generatoer
-
To create a property, we use forAll(Gen[A]) (A => Boolean) : Prop. A => Boolean represent the algebraic rule specified by the programmer
-
Prop should be composable, i.e., it needs to support && and || both of type Prop => Prop, i.e., accepts another clause and returns a combined clause
-
Prop needs to be able to check, i.e., need a check: Either[SuccessInfo, FailureInfo]
-
For Gen, often we need context-sensitive generation, e.g., first generate the size of the list, and then generate list based on size, so Gen is a monad and needs to support flatMap
-
For Gen to know how to generate, we need to pass in a State[RNG, A], where State itself is a RNG => (A, RNG)
-
For Prop to how how to run test, we need to pass the logic over, i.e., how many cases to pass before we show the result? TestCases => Result
-
Since Prop is responsible for running the check, it needs to know how to generate as well. Instead of TestCases => Result, we need a (TestCases, RNG) => Result, so Gen can accept that rng and run