gpt4 book ai didi

haskell 美味.HUnit : how to run multiple tests with IO

转载 作者:行者123 更新时间:2023-12-02 18:25:13 24 4
gpt4 key购买 nike

我正在尝试在 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(毕竟断言只是 IO ());但这可能意味着 IO 被重复执行,这不是我想要的。

或者,一个 testCase 可以包含一个调用多个断言的 do {} block ;但这意味着单个测试不可选,并且不会获得详细输出来确认运行了哪些测试。

Test.Tasty.withResource 看起来很有希望;如果它的第三个参数是 a -> TestTree,我可以使用它;然而,它不是,它是 IO a -> TestTree,我正在努力找出如何安全地提取 a 以在我的测试用例中使用。

我尝试过使用这个,但我担心我错过了一些基本的东西......

非常感谢您的帮助。

最佳答案

你看的是对的

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 测试,则不会运行)。

关于 haskell 美味.HUnit : how to run multiple tests with IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55165302/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com