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