簡體   English   中英

Haskell Tasty.HUnit:如何使用 IO 運行多個測試

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM