测试返回错误的haskell函数

时间:2017-09-23 06:09:29

标签: haskell testing

您好我有类似以下的haskell功能

test :: Int -> Bool
test 1  = error "shouldnt have been 1"
test 2  = error "shouldnt have been 2"
test 11 = error "shouldnt have been 11"
test 77 = error "shouldnt have been 77"
test _  = True

我有一个测试方案来测试错误的输入,以确保它们返回正确的错误

tc1 = test 1
tc2 = test 2
tc3 = test 11
tc4 = test 77

allTests = [tc1, tc2, tc3, tc4]

但问题是当我在ghci中运行allTests时,我只得到第一个错误。我想列出所有错误

如何做到这一点或以某种方式我能抓住错误?

1 个答案:

答案 0 :(得分:4)

您可以尝试使用catch中的Control.Exception,但这仍然是实现目标的尴尬方式。

使用纯数据类型来捕获错误会更好,因为它们更容易编写和收集。通常情况下,您可以使用Either,但在此特定情况下,成功案例不会包含任何信息,因此类型为Either String (),与Maybe String同构。重写test以返回Maybe String是微不足道的:

test :: Int -> Maybe String
test 1  = Just "shouldnt have been 1"
test 2  = Just "shouldnt have been 2"
test 11 = Just "shouldnt have been 11"
test 77 = Just "shouldnt have been 77"
test _  = Nothing

tc1 = test 1
tc2 = test 2
tc3 = test 11
tc4 = test 77
tc5 = test 5

我添加了tc5值,以证明测试成功后会发生什么。

您可以评估所有这些测试用例,但如果您只想要失败案例,则可以使用catMaybes中的Data.Maybe

allTests = catMaybes [tc1, tc2, tc3, tc4, tc5]

这是运行allTests

的结果
*Q46376632> allTests
["shouldnt have been 1",
 "shouldnt have been 2",
 "shouldnt have been 11",
 "shouldnt have been 77"]

如果您无法更改正在测试的功能,您可以尝试以下类似的功能,但它并不优雅:

tc1 = catch (print $ test 1) (\err -> print (err :: SomeException))
tc2 = catch (print $ test 2) (\err -> print (err :: SomeException))
tc3 = catch (print $ test 11) (\err -> print (err :: SomeException))
tc4 = catch (print $ test 77) (\err -> print (err :: SomeException))
tc5 = catch (print $ test 5) (\err -> print (err :: SomeException))

allTests = sequence_ [tc1, tc2, tc3, tc4, tc5]

运行时,你得到如下输出:

*Q46376632> allTests
shouldnt have been 1
CallStack (from HasCallStack):
  error, called at 46376632.hs:14:10 in main:Q46376632
shouldnt have been 2
CallStack (from HasCallStack):
  error, called at 46376632.hs:15:10 in main:Q46376632
shouldnt have been 11
CallStack (from HasCallStack):
  error, called at 46376632.hs:16:11 in main:Q46376632
shouldnt have been 77
CallStack (from HasCallStack):
  error, called at 46376632.hs:17:11 in main:Q46376632
True

此时,您可能更擅长使用适当的测试框架。