Search code examples
haskellquickcheck

Test a function with different list of value with quickCheck


I need to test a function with quickCheck with different range of values.

my function is :

prop_test (x,y,z) (i,j,k) ndiv

and I would like to perform tests with :

  • x,y,z randomly taken in the range 0 to 1000
  • i,j,k randomly taken in the range 1000 to 100000
  • ndiv randomly taken in a list of fixed values [2,5,10,20]

I managed to set one property for one argument, but I didn't find how to set multiple (different) property to the function.


Solution

  • Here's a simpler example that you should be able to adapt to your style. Assuming you have a function

    f :: Int -> Int -> Bool
    

    and you want to test if f x y evaluates to True for x in the range 0 to 10 and y in the range 10 to 20, you can do that by saying

    prop_f :: Property
    prop_f = forAll (choose ( 0, 10)) $ \ x ->
             forAll (choose (10, 20)) $ \ y ->
             f x y
    

    Another option is to combine the generation of several values into one forAll call by constructing a new generator on the fly:

    prop_f :: Property
    prop_f = forAll ((,) <$> r1 <*> r2) $ \ (x, y) -> f x y
      where
        r1 = choose ( 0, 10)
        r2 = choose (10, 20)
    

    Yet another option is to define your own newtype wrappers:

    newtype R1 = R1 Int
    newtype R2 = R2 Int
    
    instance Arbitrary R1 where arbitrary = R1 <$> choose ( 0, 10)
    instance Arbitrary R2 where arbitrary = R2 <$> choose (10, 20)
    
    prop_f :: R1 -> R2 -> Bool
    prop_f (R1 x) (R2 y) = f x y
    

    To define a generator that uses a predefined list of options, you'll have to use the elements functions.