How to Expect Exceptions with QuickCheck2
I've been trying to pick up Haskell lately, but I have some difficulties with QuickCheck2 (which I'm trying to learn by coding 99 problems). I have looked at this question and related questions.
Like the OP from the above question, I'm curious to see if it is possible for QuickCheck2 to expect an exception. I know this is possible with QuickCheck 1. Some searches have led me to the following version of my code to test a function myLast
that 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) is not checked by the typecheck as it expectFailure
returns Property
and (2) requires import from v1 QuickCheck. As for (1), I don't see how to do it - I tried to find how to catch the exceptions myself, but was met with a lot of difficulty because it started to bring the monad IO
. As for (2), I don't know if the idea of using a function is a expectFailure
good idea in the first place - can anyone who has tried with the system tell me if I should be using components from v1 and v2? If not, where is the same expectFailure
for v2 QuickCheck?
source to share
You are using expectFailure
like this:
prop :: Int -> Bool
prop x = x + 1 == x -- should always be False
main = quickCheck (expectFailure prop)
However, it expectFailure
verifies that there is at least one test case that fails - that is, it actually expects your code to fail. You want QuickCheck to ignore any glitches in case it has passed an empty list before prop_myLast
.
One way to do this is with an 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 that do not match the conditional.
Update. One way to explicitly test the case []
:
quickCheck $ expectFailure $ seq (myLast []) True
The expression seq a True
will return True
if it a
doesn't throw an exception or diverge.
source to share