Testing I / O with Monadic QuickCheck

Can someone give me a brief example of testing I / O using Monadic QuickCheck?

+47
io haskell quickcheck
Feb 14 '10 at 2:27
source share
2 answers

The Test.QuickCheck.Monadic module allows you to test monadic code, even those that work in IO .

The monadic property test is of type PropertyM ma , where m is the monad in which the test passes and a is ultimately ignored. In the case of PropertyM IO a you convert the monadic test to Property using monadicIO ; for all other monads, you use monadic instead (which takes a function to run the monad, something IO doesn't have).

In a monadic test, the value of return ed from the monad is ignored. To test the expression, use assert ; assert false value will complete the test. Use run to execute code in the monad being checked.

Other monadic actions are at your disposal. For example, pick will generate new test inputs from Gen a , and pre will check the test prerequisites. They are useful if the test inputs or preconditions themselves depend on the values โ€‹โ€‹calculated through the monad being tested, in which case the normal way of generating the inputs or checking the preconditions will not work.

Here is an example of testing some IO code: we verify that after writing something to a temporary file, we can read the same data back. For demonstration purposes, we will impose a prerequisite so that we write at least one byte to a file. Two test properties do the same; one uses pick and pre unnecessarily, and the other does not.

 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 
+54
May 31 '10 at 11:45
source share

The standard link for testing the monadic code is "Testing the Monadic Code with QuickCheck" . It shows various testing methods in the context of a monad, such as IO.

But you should consider posting a more specific question about what you want to check.

+7
Feb 15 '10 at 1:59
source share



All Articles