Reputation: 389
Chapter 8 in FP in Scala talks about property based testing and covers how to build a library from scratch. A high level summary of the API is included below:
//generator of random test cases
case class Gen[+A](sample: State[RNG,A])
//generator of random test cases with specified size
case class SGen[+A](g: Int => Gen[A])
//property that runs assertion
case class Prop(run: (MaxSize,TestCases,RNG) => Result)
//combines random generator with predicates and returns a property
def forAll[A](g: Int => Gen[A])(f: A => Boolean): Prop
The following implementation of forAll
first creates a sequence of properties, each with an size of 0,1,...max (or n, whichever is lower). It then creates a single property by combining them with &&
while setting the number of test cases per property to casesPerSize
def forAll[A](g: Int => Gen[A])(f: A => Boolean): Prop = Prop {
(max,n,rng) =>
val casesPerSize = (n - 1) / max + 1
val props: Stream[Prop] =
Stream.from(0).take((n min max) + 1).map(i => forAll(g(i))(f))
val prop: Prop =
props.map(p => Prop { (max, n, rng) =>
p.run(max, casesPerSize, rng)
}).toList.reduce(_ && _)
prop.run(max,n,rng)
}
What I do not understand is why casesPerSize is calculated as
val casesPerSize = (n - 1) / max + 1
Taking a specific example, if I assume n=95, max=10
then there will be 11 properties with size from 0 to 10, each of which will generate 10 test cases. Since there is just 1 unique test case for size 0, that would still mean 110 - 9 = 101 unique test cases. So how does it ensure that no more than n test cases are generated?
Upvotes: 2
Views: 128
Reputation: 1
I think that the formula for calculation casesPerSize was chosen quite arbitrarily. As well as the formula for calculating the maximum test length take((n min max) + 1).
Upvotes: 0