使用Monadic QuickChecktestingIO操作
任何人都可以给我一个使用Monadic QuickChecktestingIO操作的简单例子吗?
Test.QuickCheck.Monadic模块让你testing一元代码,甚至是在IO
中运行的东西。
monadic属性testing的types是PropertyM ma
,其中m
是testing运行的monad,并且a
最终被忽略。 在PropertyM IO a
的情况下,使用monadicIO
将monadicIO
testing转换为Property
; 对于所有其他monad,您使用monadic
(这需要一个函数来运行monad, IO
没有)。
在monadictesting中,从monad return
的值return
被忽略。 要检查expression式,请使用assert
; assert
一个错误的值将会使testing失败。 使用run
来执行正在testing的monad中的代码。
还有其他一些单一的行动在你的处置。 例如, pick
将从Gen a
生成新的testinginput, pre
将检查testing前提条件。 如果testinginput或前提条件本身依赖于通过被测单子计算得到的值,那么这很有用,在这种情况下,生成input或检查预条件的正常方式将不起作用。
下面是testing一些IO
代码的例子:我们检查在写入临时文件之后,我们可以读取相同的数据。 出于演示目的,我们将强加一个先决条件,即我们至less向文件写入一个字节。 这两个testing属性做同样的事情; 一个不必要地使用pick
和pre
,另一个不使用。
import System.Directory (removeFile) import System.IO (hGetContents, hPutStr, hSeek, openBinaryTempFile, SeekMode (..)) import Test.QuickCheck (arbitrary, Property, quickCheck, (==>)) import Test.QuickCheck.Monadic (assert, monadicIO, pick, pre, run) -- Demonstrating pick and pre as well: prop_writeThenRead :: Property prop_writeThenRead = monadicIO $ do writtenData <- pick arbitrary pre $ not (null writtenData) readData <- run $ writeThenRead writtenData assert $ writtenData == readData -- A more idiomatic way to write the above: prop_writeThenRead2 :: [Char] -> Property prop_writeThenRead2 writtenData = not (null writtenData) ==> monadicIO test where test = do readData <- run $ writeThenRead writtenData assert $ writtenData == readData writeThenRead :: [Char] -> IO [Char] writeThenRead output = do (path, h) <- openBinaryTempFile "/tmp" "quickcheck.tmp" removeFile path hPutStr h output hSeek h AbsoluteSeek 0 hGetContents h main :: IO () main = do quickCheck prop_writeThenRead quickCheck prop_writeThenRead2
testing一元代码的标准参考是“使用QuickChecktestingMonadic代码” 。 它显示了在诸如IO之类的monad环境下的各种testing方法。
但是你真的应该考虑发布一个更具体的问题,说明你想testing什么。