如何使用QuickCheck2预期异常

时间:2014-12-12 04:29:47

标签: haskell

我最近一直试图接收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在哪里?

1 个答案:

答案 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