避免重复的QuickCheck属性

时间:2011-10-05 18:05:44

标签: haskell quickcheck

我开始通过解决99个Haskell问题来学习Haskell。 http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell_Problems我想使用quickcheck为每个程序/函数编写测试。

我有以下代码:

import Test.QuickCheck
import Text.Printf

main  = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests

-- 1
myLast  lst = last lst
prop_1a xs x = myLast  (xs ++ [x]) == (x::String)

myLast' = head . reverse
prop_1b xs x = myLast' (xs ++ [x]) == (x::String)

tests  = [("1a",                 quickCheck prop_1a)
         ,("1b",                 quickCheck prop_1b)
         ]

我可能会写myLast''myLast'''等。有没有办法可以测试所有这些方法,而无需重复代码和快速检查属性?

相关问题:现在,我正在快速检查使用字符串。有没有办法随机使用不同类型进行测试?

2 个答案:

答案 0 :(得分:6)

只需将该函数作为另一个参数进行测试:

prop_1 last xs x = last (xs ++ [x]) == (x :: Int)

tests = zipWith mkTest ['a'..] [myLast, myLast']
  where mkTest letter func = ('1':[letter], quickCheck $ prop_1 func)

答案 1 :(得分:2)

  

有没有办法可以测试所有这些方法,而无需重复代码和快速检查属性?

为什么不编写道具以便它需要一个函数列表,然后对每个函数进行检查?然后你将它作为quickCheck (myProp [myLast, myLast', myLast''])运行。

编辑:我担心你可能会问:P要像我上面所说的那样,myProp应该列出一系列函数,所有函数都与last具有相同的类型,并返回布尔值:

myProp :: [([a] -> a)] -> Bool

但是现在我看着它,它可能会更好(并且更类似于你原来的方法)让它也需要一个列表和一个项目,所以我想我会这样做:

myProp :: [([a] -> a)] -> [a] -> a -> Bool

如果列表为空,则返回true:

myProp [] _ _ = True

如果没有,那么我们检查属性是否适用于列表中的第一个函数,然后递归检查列表的其余部分:

myProp [f:fs] xs x = f (xs ++ [x]) == x && myProp fs xs x

(我不确定你为什么在你的实现中写x::String。我认为你不应该需要它 - last适用于任何事物的列表,而不仅仅是字符串列表。但是我实际上没有测试过这个,所以我认为你有充分的理由。)

无论如何,我认为应该可行,但我还没有尝试过。请随意编辑和修复我可能做出的任何愚蠢的语法错误。