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 choose
but 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