Prueba de acciones IO con Monádica QuickCheck
-
20-09-2019 - |
Pregunta
Puede alguien dar un breve ejemplo de pruebas acciones IO utilizando Monádica QuickCheck?
Solución
El Test.QuickCheck módulo .Monadic le permite probar el código monádico, incluso cosas que se ejecutan en IO
.
Una prueba monádica propiedad es de tipo PropertyM m a
, donde m
es la mónada la prueba se ejecuta en a
y en última instancia, se ignora. En el caso de PropertyM IO a
, convertir la prueba monádica a un Property
utilizando monadicIO
; para todos los demás mónadas, en lugar de utilizar monadic
(que tiene una función para ejecutar la mónada, algo IO
no tiene).
En un ensayo monádico, el valor return
ed de la mónada se ignora. Para comprobar una expresión, utilizar assert
; assert
ing un valor falso fallará la prueba. Utilice run
para ejecutar el código en la mónada está probando.
Hay otras acciones monádicos a su disposición. Por ejemplo, pick
generará nuevas entradas de prueba de cada una Gen a
y pre
comprobará condiciones de prueba. Estos son útiles si las entradas de prueba o de las propias condiciones previas dependen de los valores calculados a través de la mónada que se prueba, en cuyo caso la forma normal de la generación de entradas o control de precontions no funcionará.
Este es un ejemplo de probar algo de código IO
: comprobamos que después de escribir algo en un archivo temporal, podemos leer que los mismos datos de nuevo. Para fines de demostración, vamos a imponer la condición de que escribimos al menos un byte en el archivo. Las dos propiedades de las pruebas hacen lo mismo; uno utiliza 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
Otros consejos
La referencia estándar para probar código monádico es "Código Monádica de pruebas con QuickCheck ". Se muestra varias formas de las pruebas en el contexto de una mónada tales como IO.
Pero lo que realmente debe considerar la publicación de una pregunta más concreta acerca de qué es lo que le gustaría probar.