I have a function arbExample to generate a random Example data type which depends on a numbers of functions.
I am trying to do some property testing by doing quickCheck prop_example, the problem is I don't know how to define an Arbitrary instance for Example which uses arbExample.
I like to be able run quickCheck prop_example while specifying the Gens data structure which arbExample uses.
data Example = Example
{ myInt :: Int
, myList :: [String]
} deriving (Show)
data Gens = Gens
{ gen1 :: Gen Int
, gen2 :: Gen String }
arbExample :: Gens -> Gen Example
arbExample gens = do
i <- gen1 gens
xs <- vectorOf i (gen2 gens)
return Example{myInt=i, myList=xs}
prop_example :: Example -> Property
prop_example example = do
let len = length (myList example)
monadicIO $ do
-- result of running some program
successful <- run $ (\e -> return False) example
case successful of
True -> return ()
False -> fail "failure "
instance Arbitrary Example where
arbitrary = arbExample _ {- ??? -}
Use the forAll combinator which has the signature:
forAll :: (Show a, Testable prop) => Gen a -> (a -> prop) -> Property
A quick example:
import Test.QuickCheck
genA :: Gen Int
genA = choose (-100,100)
genB :: Gen Int
genB = choose (1,100)
prop_example :: Int -> Bool
prop_example n = n > 0
testA = quickCheck $ forAll genA prop_example
testB = quickCheck $ forAll genB prop_example
testA will fail but testB will succeed.
来源:https://stackoverflow.com/questions/27073531/quickcheck-defining-arbitrary-instances-using-a-function-whose-result-depends-o