I have a function with the following type signature
rndListIndex :: Double -> Double -> Double -> Double
rndListIndex maxIdx r1 r2 = …
the function has the property of
prop_alwaysLessThanMaxIdx idx r1 r2 = (rndListIndex idx r1 r2 <= idx)
how do I generate random data for maxIdx and r1,r2 separately; I know of the function choosebut do not know how to use it with more than one input variable.
For now I have tested the Property with fixed idx, which is not the way it should be tested.
In QuickCheck, test data is produced by test generators whose types are of the form Gen a. Gen a is a generator for values of type a. A type can define a default test data generator by defining an instance of the class Arbitrary:
If you want to get the counterexample as a Haskell value, rather than just printing it, try the quickcheck-with-counterexamples package. Args specifies arguments to the QuickCheck driver
To run more tests you can use the withMaxSuccess combinator: >>> quickCheck (withMaxSuccess 10000 prop_reverse) +++ OK, passed 10000 tests. To use QuickCheck on your own data types you will need to write Arbitrary instances for those types.
For the curious, the return [] is a Template Haskell splice that makes GHC insert the empty list of declarations at that point in the program; GHC typechecks everything before the return [] before it starts on the rest of the module, which means that the later call to quickCheckAll can see everything that was defined before the return [].
You have to use the forAll function from QuickCheck. It has the following type:
forAll :: (Show a, Testable prop)
=> Gen a -- ^ The generator to use for generating values
-> (a -> prop) -- ^ A function which returns a testable property
-> Property
forAll takes two arguments:
Testable, for example another Property, Bool or a function. Example of a nested forAll with the choose and elements generators:
-- This generates a Property p for all x's in the closed interval [1,3]
-- The property p in turn generates a property q for all y ∈ [4,5]
-- The property q is True if x < y.
prop_choose = forAll (choose (1,3)) $ \x ->
forAll (elements [4,5]) $ \y -> x < y
For your test property, you can use forAll with choose for the second and third argument.
For the first argument, there is the Positive a type in QuickCheck which can be used to generate arbitrary positive values of type a (It has an Arbitrary instance when a is a Num):
prop_alwayLessThanMaxIdx :: Positive Integer -> Property
prop_alwaysLessThanMaxIdx (Positive idx) =
forAll (choose (0,1)) $ \r1 ->
forAll (choose (0,1)) $ \r2 ->
(rndListIndex idx r1 r2) < idx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With