[英]Haskell Tasty.HUnit : how to run multiple tests with IO
我正在嘗試在 Test.Tasty testGroup 中運行多個測試(即多個斷言); 但是輸入從 IO 讀入的單個“對象”。
例如,我讀取並解析一個文件; 我想對該文件的結果進行多次斷言。 就像是
tests :: [String] -> TestTree
tests ls = testGroup "tests" [ testCase "length" $ length ls @?= 2
, testCase "foo" $ ls !! 0 @?= "foo"
]
main = do
ls :: [String] <- read <$> readFile "/tmp/hunit"
defaultMain (tests ls)
但是,以上要求在調用測試之前執行 IO; 並且即使僅請求測試的子集(無論該子集是否實際使用 IO 結果)也會執行。
或者,每個 testCase 都可以執行自己的 IO(畢竟 Assertion 就是 IO()); 但這可能意味着重復執行 IO,這不是我想要的。
或者,一個 testCase 可以包含一個調用多個斷言的do {}
塊; 但這意味着單個測試是不可選擇的,並且不會獲得詳細的輸出來確認運行了哪些測試。
Test.Tasty.withResource
看起來很有希望; 如果它的第三個參數是a -> TestTree
,我可以使用它; 然而,它不是,它是IO a -> TestTree
,我正在努力研究如何安全地提取a
以在我的測試用例中使用。
我試過玩這個,但我擔心我錯過了一些基本的東西......
感激地收到任何幫助。
看起來應該很簡單; 因為type Assertion = IO ()
,這兩個部分應該足夠了:
(>>=) :: IO a -> (a -> Assertion) -> Assertion
testCase :: TestName -> Assertion -> TestTree
你是正確的看着
withResource
:: IO a -- ^ initialize the resource
-> (a -> IO ()) -- ^ free the resource
-> (IO a -> TestTree)
-- ^ @'IO' a@ is an action which returns the acquired resource.
-- Despite it being an 'IO' action, the resource it returns will be
-- acquired only once and shared across all the tests in the tree.
-> TestTree
我們的想法是您可以將您的場景編寫為:
tests :: IO String -> TestTree
tests lsIO = testGroup "tests"
[ testCase "length" $ do
ls <- lsIO
length ls @?= 2
, testCase "foo" $ do
ls <- lsIO
ls !! 0 @?= "foo"
, testCase "no io" $ do
return ()
]
main :: IO ()
main = defaultMain (withResource acquire tests)
acquire :: IO [String]
acquire = read <$> readFile "/tmp/hunit"
即它看起來你多次讀取文件,但tasty
只執行一次動作。 這就是評論所說的:)嘗試將putStrLn "trace debug"
添加到acquire
以確定它大部分運行一次(即如果你只是要求no io
測試則不運行)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.