简单的haskellunit testing

我想通过99个Haskell问题 ,我想专注于解决scheme,但与testing。 如果我将第一个问题的解决scheme作为3行.hs文件,

 myLast :: [a] -> a myLast [x] = x myLast (_:xs) = myLast xs 

什么是我可以添加到这个最小的代码量,以便我可以添加内联testing,并与runhaskell运行它们?

QuickCheck(基本上为您生成testinginput)可能是testing纯函数的最好方法。 如果有问题的函数有标准库中的模拟函数,那么可以使用标准函数作为模型来testing你的函数:

 {-# LANGUAGE TemplateHaskell #-} import Test.QuickCheck import Test.QuickCheck.All myLast :: [a] -> a myLast [x] = x myLast (_:xs) = myLast xs -- here we specify that 'myLast' should return exactly the same result -- as 'last' for any given 'xs' prop_myLast xs = myLast xs == last xs return [] -- need this for GHC 7.8 -- quickCheckAll generates test cases for all 'prop_*' properties main = $(quickCheckAll) 

如果你运行它,你会得到:

 === prop_myLast on tmp3.hs:12 === *** Failed! Exception: 'tmp3.hs:(7,1)-(8,25): Non-exhaustive patterns in function myLast' (after 1 test): [] False 

因为你的myLast不处理[]情况(它应该,但应该可能会抛出像'最后'错误)。 但是在这里我们可以简单地调整我们的testing,但是指定只应该使用非空string(使用==> combinator):

 prop_myLast xs = length xs > 0 ==> myLast xs == last xs 

这使得所有100个自动生成的testing用例都可以通过myLast

 === prop_myLast on tmp3.hs:11 === +++ OK, passed 100 tests. True 

PS指定myLast行为的另一种方法可能是:

 prop_myLast2 x xs = myLast (xs++[x]) == x 

或更好:

 prop_myLast3 x xs = x `notElem` xs ==> myLast (xs++[x]) == x 

hspec也是一个Haskell的testing框架,它受Ruby RSpec的启发。 它集成了QuickCheck,SmallCheck和HUnit。