代码之家  ›  专栏  ›  技术社区  ›  Bill

使用Monadic QuickCheck测试IO操作

  •  49
  • Bill  · 技术社区  · 16 年前

    有谁能给我一个简单的例子来测试IO操作使用一元快速检查?

    2 回复  |  直到 15 年前
        1
  •  59
  •   Paul Kuliniewicz    16 年前

    这个 Test.QuickCheck.Monadic IO .

    一元属性测试属于 PropertyM m a m 是测试运行的单子 a PropertyM IO a ,将一元测试转换为 Property 通过使用 monadicIO ; 对于所有其他单子,你使用 monadic 相反(它需要一个函数来运行monad,或者 木卫一 没有)。

    在一元测试中,值 return 从单子中提取的信息被忽略。要检查表达式,请使用 assert 断言 输入一个假值将使测试失败。使用 run 在被测单子中执行代码。

    pick 将从 Gen a ,和 pre 将检查测试前提条件。如果测试输入或预条件本身依赖于通过被测试的monad计算出的值,那么这些是有用的,在这种情况下,生成输入或检查预条件的常规方法将不起作用。

    木卫一 代码:我们检查在将某些内容写入临时文件后,是否可以读回相同的数据。出于演示的目的,我们将施加一个先决条件,即至少向文件写入一个字节。两个测试属性做相同的事情;使用 挑选 和 之前

    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
  •  7
  •   Helmut Grohne    12 年前

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

    但你确实应该考虑一个更具体的问题,那就是你想测试什么。