Reputation: 1652
I've been trying to pick up Haskell recently, but I am having some difficulty with QuickCheck2 (which I'm trying to learn while coding up the 99 problems). I've looked at this question along with related ones on the matter.
Like OP from the aforementioned question, I'm interested in finding out whether it is possible for QuickCheck2 to expect exceptions. I know this is possible with QuickCheck 1. Some googling around led me to the following version of my code to test a myLast
function which returns the last element of a list:
prop_myLast :: [Int] -> Bool
prop_myLast [] = expectFailure . myLast $ []
prop_myLast xs = myLast xs == last xs
Of course, this (1) does not typecheck, since expectFailure
returns a Property
and (2) requires an import from v1 of QuickCheck. Regarding (1) I don't really see how to make this work - I tried looking up how to catch exceptions on my own but was met with more difficulty because this started bringing in the IO
monad. With respect to (2) I don't know if bringing in the expectFailure
function is a good idea in the first place - could anyone experienced with the system tell me if I'm supposed to be using components from both v1 and v2? If not, where is the analogous expectFailure
for v2 of QuickCheck?
Upvotes: 5
Views: 496
Reputation: 52049
You use expectFailure
like this:
prop :: Int -> Bool
prop x = x + 1 == x -- should always be False
main = quickCheck (expectFailure prop)
However, expectFailure
only tests that there is at least one test case which fails - i.e. it really expects your code to fail. You want QuickCheck to ignore any failures in the event that it passes the empty list to prop_myLast
.
One way to do this is with the ==>
operator:
prop_myLast :: [Int] -> Property
prop_myLast xs = not (null xs) ==> myLast xs == last xs
Another example:
prop_cubed :: Int -> Property
prop_cubed x = (x > 1) ==> x^3 > x -- note: not true for negative values so don't
-- test those cases
Quickcheck will discard generated test cases which do not match the conditional.
Update: One way of explicitly testing the []
case is:
quickCheck $ expectFailure $ seq (myLast []) True
The expression seq a True
will return True
unless a
throws an exception or diverges.
Upvotes: 4