我正在使用QuickCheck
测试以下程序:
{-# LANGUAGE TemplateHaskell #-}
import Test.QuickCheck
import Test.QuickCheck.All
elementAt :: (Integral b) => [a] -> b -> a
elementAt [x] _ = x
elementAt (x:xs) 1 = x
elementAt (x:xs) b = elementAt xs (b - 1)
prop_elementAt xs b = length xs > 0 && b >= 0 && b < length xs ==> elementAt xs (b + 1) == xs !! b
main = $(quickCheckAll)
尽管响应有所不同,但我不断收到消息
*** Gave up! Passed only x tests.
这是我应该关注的事情吗?还是测试输入的性质决定了QuickCheck将运行多长时间?
最佳答案
==>
的工作方式是:首先快速检查将为xs
和b
生成随机值,然后检查是否仅满足谓词length xs > 0 && b >= 0 && b < length xs
,然后将检查属性的可满足性。
由于会生成多少个测试用例是有限制的,因此可能很多时候以上谓词都无法满足。因此,在生成足够的有效测试用例(满足谓词)之前,快速检查就放弃了。
您应该改为将Arbitrary
实例声明为新类型,以仅生成满足这些谓词的测试用例。
{-# LANGUAGE TemplateHaskell #-}
import Test.QuickCheck
import Test.QuickCheck.All
elementAt :: (Integral b) => [a] -> b -> a
elementAt [x] _ = x
elementAt (x:xs) 1 = x
elementAt (x:xs) b = elementAt xs (b - 1)
prop_elementAt (Foo xs b) = elementAt xs (b + 1) == xs !! b
data Foo a b = Foo [a] b deriving (Show)
instance (Integral b, Arbitrary a, Arbitrary b) => Arbitrary (Foo a b) where
arbitrary = do
as <- listOf1 arbitrary -- length xs > 0
b <- choose (0,length as - 1) -- b >= 0 and b < length xs
return (Foo as $ fromIntegral b)
main = $(quickCheckAll)
关于testing - 为什么QuickCheck放弃了?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18502798/