Domanda

Qualcuno mi può dare un breve esempio di testare azioni IO utilizzando Monadica QuickCheck?

È stato utile?

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 returned fuori della monade viene ignorato. Per controllare un'espressione, utilizzare assert; asserting 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top