简单的 Haskell 单元测试 [英] Simple haskell unit testing
问题描述
我想了解 99 Haskell 问题,并且我想专注于解决方案,但有测试.如果我将第一个问题的解决方案作为 3 行 .hs
文件,
I want to go through 99 Haskell Problems, and I want to concentrate on the solution but with testing. If I have the solution to the first problem as a 3 line .hs
file,
myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs
我可以添加的最少代码量是多少,以便我可以内联添加测试并使用 runhaskell
运行它们?
What is the minimal amount of code I can add to this so that I can add tests inline and run them with runhaskell
?
推荐答案
QuickCheck(基本上为您生成测试输入)可能是测试纯函数的最佳方式.如果有问题的函数有来自标准库的模拟,您可以使用标准库作为模型来测试您的函数:
QuickCheck (which basicaly generates test inputs for you) is probably the best way to test pure function. And if a function in question has an analog from the standard library you can just test your function using the standard one as a model:
{-# 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)
如果你运行它,你会得到:
If you run it you'll get:
=== 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
不处理 []
情况(它应该但可能应该抛出像last"这样的错误).但在这里我们可以简单地调整我们的测试,但指定只应使用非空字符串(使用 ==>
组合器):
because your myLast
doesn't handle []
case (it should but should probably throw an error like 'last').
But here we can simply adjust our test but specifying that only non-empty strings should be used (using ==>
combinator):
prop_myLast xs = length xs > 0 ==> myLast xs == last xs
这使得所有 100 个自动生成的测试用例都通过 myLast
:
Which makes all 100 auto-generated test cases to pass for myLast
:
=== prop_myLast on tmp3.hs:11 ===
+++ OK, passed 100 tests.
True
PS 另一种指定 myLast
行为的方法可能是:
PS Another way to specify myLast
behavior may be:
prop_myLast2 x xs = myLast (xs++[x]) == x
或者更好:
prop_myLast3 x xs = x `notElem` xs ==> myLast (xs++[x]) == x
这篇关于简单的 Haskell 单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!