提问人:Øyvind Roth 提问时间:11/13/2023 最后编辑:Øyvind Roth 更新时间:11/20/2023 访问量:74
如何在 Haskell Tasty 测试中捕获 stdout 并模拟 stdin?
How do I capture stdout and simulate stdin in a Haskell Tasty test?
问:
我的不纯函数定义如下:
module HangmanImpure (HangmanImpure.getLine, HangmanImpure.putStr, HangmanImpure.putStrLn, HangmanImpure.strlen) where
import qualified System.IO as Sys
getLine :: IO String
getLine = do x <- Sys.getChar
if x == '\n' then
return []
else
do xs <- HangmanImpure.getLine
return (x:xs)
putStr :: String -> IO ()
putStr [] = return ()
putStr (x:xs) = do Sys.putChar x
HangmanImpure.putStr xs
我想使用 Tasty 测试这些功能,例如:
module TestHangmanImpure (scProps) where
import qualified Test.Tasty as T
import qualified Test.Tasty.SmallCheck as SC
import qualified HangmanImpure as HI (getLine, putStr, putStrLn, strlen)
scProps :: T.TestTree
scProps = T.testGroup "checked by SmallCheck"
[
SC.testProperty "getLine should return what is written to stdin" $
"Placeholder to get the test to run" == "Placeholder to get the test to run" -- HI.getLine == IO "Hello" -- PLEASE, HELP ME WITH SOME CONTENT HERE
, SC.testProperty "putStr should write to stdout what it gets in as an argument" $
"Placeholder to get the test to run" == "Placeholder to get the test to run" -- HI.putStr "Nice day!" -- PLEASE, HELP ME WITH SOME CONTENT HERE
]
如果有人能在我指出的两个简单测试中填写身体,我将不胜感激。
编辑:
我认为[在 haskell 中,我如何与 stdin 的交互?[1] 可以引导我找到解决方案。我可以让该解决方案在我的 Win10 上使用 HSpec。所以这个问题几乎是重复的。但是我无法使用 Tasty.HUnit 让它工作。我的暂定代码运行如下:IO ()
module TestUtilImpure (scProps, qcProps, uTests, properties) where
import qualified Test.Tasty as T
import qualified Test.Tasty.HUnit as HU
import StdInStdOutUtil as IOU (captureStdout, provideStdin)
import UtilImpure as UI (getLine)
properties :: T.TestTree
properties = T.testGroup "TestUtilImpure tests" [
uTests
]
uTests :: T.TestTree
uTests = T.testGroup "Checked by HUnit"
[
HU.testCase "UI.getLine reading from stdin should return what was provided" $ do
let line = "Hello, echo!\n"
let capturedIOString = IOU.captureStdout (provideStdin line echo)
capturedString <- capturedIOString
HU.assertBool "The String returned from UI.getLine differs from the one provided for StdIn" $ capturedString == line
]
echo :: IO ()
echo = UI.getLine >>= Prelude.putStrLn
(我把 [1] 中的解决方案:在 haskell 中,我如何与“IO()”的 stdin 交互?
import StdInStdOutUtil as IOU (captureStdout, provideStdin)
我的测试失败:
从 UI.getLine 返回的 String 与为 标准输入
无论我测试 Prelude.getLine 还是我自己的 UI.getLine,我都会收到相同的错误消息。所以我想有一些我不理解的语法使用 Tasty 失败了。
答: 暂无答案
评论
getLine
getLine
getLine
stdin
getLine :: StdIn -> IO String
StdIn
stdin
String -> String
IO
smallcheck
\n
reverse (reverse xs) == xs
xs
reverse :: [a] -> [a]
reverse
reverse
[a]
reverse
getLine
IO String
getLine
withResourceSource