【问题标题】:Testing IO actions with Monadic QuickCheck使用 Monadic QuickCheck 测试 IO 操作
【发布时间】:2011-01-16 15:00:30
【问题描述】:

谁能给我一个使用 Monadic QuickCheck 测试 IO 操作的简短示例?

【问题讨论】:

  • 举一个你想测试的例子,会让问题变得更好。

标签: haskell io quickcheck


【解决方案1】:

Test.QuickCheck.Monadic 模块让您可以测试一元代码,甚至是在 IO 中运行的东西。

一元属性测试的类型为PropertyM m a,其中m 是测试运行的单子,a 最终会被忽略。对于PropertyM IO a,您可以使用monadicIO 将一元测试转换为Property;对于所有其他 monad,您使用 monadic 代替(它需要一个函数来运行 monad,IO 没有)。

在单子测试中,单子中的值returned 被忽略。要检查表达式,请使用assertassert错误值将导致测试失败。使用run 执行正在测试的 monad 中的代码。

您可以使用其他单子操作。例如,pick 将从Gen a 生成新的测试输入,pre 将检查测试前提条件。如果测试输入或前置条件本身依赖于通过被测试的 monad 计算的值,则这些很有用,在这种情况下,生成输入或检查前置条件的正常方法将不起作用。

这是一个测试一些IO 代码的示例:我们检查在将某些内容写入临时文件后,我们是否可以读回相同的数据。出于演示目的,我们将强加一个先决条件,即我们将至少一个字节写入文件。这两个测试属性做同样的事情;一个不必要地使用pickpre,而另一个则没有。

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

【讨论】:

    【解决方案2】:

    测试一元代码的标准参考是"Testing Monadic Code with QuickCheck"。它显示了在 IO 等 monad 的上下文中进行测试的各种方法。

    但你真的应该考虑发布一个更具体的问题,说明你想测试什么。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多