你可以嘗試使用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
在這一點上,你可能會使用適當的測試框架的更好。
嗨,謝謝。我喜歡用'TC1 =捕捉(打印$測試1)(\ ERR - >打印(ERR :: SomeException))的代碼塊''...' – Jhoy
我有一個問題,如果我有即'列表ALLTESTS = [tc1,tc2,tc3,tc4]'我可以在這個列表上使用類似的東西來減少重複代碼嗎? – Jhoy
@Jhoy首先,明白'catch'代碼並不優雅,甚至不合適,Haskell代碼。也就是說,你可以在'[a]'上使用'map'(或'fmap')。 –