azioni Testing IO con Monadica QuickCheck
-
20-09-2019 - |
Domanda
Qualcuno mi può dare un breve esempio di testare azioni IO utilizzando Monadica QuickCheck?
Soluzione
Il Test.QuickCheck modulo .Monadic ti permette di provare il codice monade, anche le cose che vengono eseguiti in IO
.
Un test di proprietà monadica è di tipo PropertyM m a
, dove m
è la monade il test viene eseguito in e a
è in ultima analisi ignorata. Nel caso di PropertyM IO a
, si converte il test monadica ad un Property
utilizzando monadicIO
; per tutte le altre monadi, si utilizza invece monadic
(che prende una funzione per eseguire la monade, qualcosa IO
non ha).
In un test monade, il valore return
ed fuori della monade viene ignorato. Per controllare un'espressione, utilizzare assert
; assert
ing un valore falso fallirà il test. Utilizzare run
per eseguire il codice nella monade in fase di test.
Non ci sono altre azioni monadici a vostra disposizione. Ad esempio, pick
genererà nuovi ingressi di prova su un Gen a
e pre
controllerà precondizioni prova. Questi sono utili se gli ingressi o precondizioni stessi prova dipendono dai valori calcolati tramite la monade fase di test, nel qual caso il modo normale di generare ingressi o di controllo precontions non funzionerà.
Ecco un esempio di testare codice IO
: controlliamo che dopo aver scritto qualcosa in un file temporaneo, possiamo leggere che i medesimi dati indietro. A scopo dimostrativo, noi imponiamo la condizione che si scrive almeno un byte del file. Le due proprietà di prova fanno la stessa cosa; uno usa pick
e pre
inutilmente, mentre l'altro 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
Altri suggerimenti
Il riferimento standard per testare il codice monadica è "Test Codice Monadica con QuickCheck ". Essa mostra vari modi di test nel contesto di una monade come IO.
Ma si dovrebbe davvero prendere in considerazione la pubblicazione di una domanda più concreta su ciò che è che si desidera testare.