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