我最近一直试图接收Haskell,但我在使用QuickCheck2时遇到了一些困难(我在编写99个问题时试图学习)。我已经查看了this question以及相关问题。
与上述问题中的OP一样,我有兴趣了解QuickCheck2是否可能出现异常情况。我知道这可以通过QuickCheck 1.一些谷歌搜索引导我到我的代码的以下版本来测试myLast
函数,它返回列表的最后一个元素:
prop_myLast :: [Int] -> Bool
prop_myLast [] = expectFailure . myLast $ []
prop_myLast xs = myLast xs == last xs
当然,这个(1)没有进行类型检查,因为expectFailure
返回Property
,而(2)需要从QuickCheck的v1导入。关于(1)我真的不知道如何做这项工作 - 我试着查看如何自己捕捉异常,但遇到了更多困难,因为这开始引入IO
monad。关于(2)我不知道是否首先引入expectFailure
功能是一个好主意 - 任何有系统经验的人都可以告诉我,我是否应该使用v1和v2的组件?如果没有,QuickCheck v2的类似expectFailure
在哪里?
答案 0 :(得分:3)
您可以像这样使用expectFailure
:
prop :: Int -> Bool
prop x = x + 1 == x -- should always be False
main = quickCheck (expectFailure prop)
但是,expectFailure
仅测试至少有一个测试用例失败 - 即它确实希望您的代码失败。您希望QuickCheck在将空列表传递给prop_myLast
时忽略任何失败。
执行此操作的一种方法是使用==>
运算符:
prop_myLast :: [Int] -> Property
prop_myLast xs = not (null xs) ==> myLast xs == last xs
另一个例子:
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 $ expectFailure $ seq (myLast []) True
除非seq a True
引发异常或分歧,否则表达式True
将返回a
。