haskell io quickcheck

haskell - Prueba de acciones de IO con Monadic QuickCheck



(2)

¿Alguien puede darme un breve ejemplo de prueba de acciones de IO usando Monadic QuickCheck?


La referencia estándar para probar el código monádico es "Probando el código monádico con QuickCheck" . Muestra varias formas de prueba en el contexto de una mónada, como IO.

Pero realmente debería considerar publicar una pregunta más concreta sobre qué es lo que le gustaría probar.


El módulo Test.QuickCheck.Monadic permite probar el código monádico, incluso las cosas que se ejecutan en IO .

Una prueba de propiedad monádica es de tipo PropertyM ma , donde m es la mónada en la que se ejecuta la prueba y finalmente se ignora. En el caso de PropertyM IO a , convierta la prueba monádica a una Property utilizando monadicIO ; para todas las otras mónadas, usas monadic (que toma una función para ejecutar la mónada, algo que IO no tiene).

En una prueba monádica, el valor return ed fuera de la mónada se ignora. Para verificar una expresión, use assert ; assert un valor falso no pasará la prueba. Use run para ejecutar el código en la mónada que se está probando.

Hay otras acciones monádicas a su disposición. Por ejemplo, pick generará nuevas entradas de prueba a partir de una Gen a , y pre comprobará las condiciones previas de la prueba. Estos son útiles si las entradas de prueba o las condiciones previas dependen de los valores calculados a través de la mónada que se está probando, en cuyo caso la forma normal de generar entradas o verificar las precondiciones no funcionará.

Aquí hay un ejemplo de prueba de algunos códigos IO : comprobamos que después de escribir algo en un archivo temporal, podemos leer esos mismos datos. Para fines de demostración, impondremos la condición previa de que escribamos al menos un byte en el archivo. Las dos propiedades de prueba hacen lo mismo; uno usa pick y pre innecesariamente mientras que el otro no.

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