Question

Quelqu'un peut-il me donner un bref exemple de tester les actions IO en utilisant Monadique QuickCheck?

Était-ce utile?

La solution

Le Test.QuickCheck Module .Monadic vous permet de tester le code monadique, même des choses qui vont dans IO.

Un test de propriété monadique est de type PropertyM m a, où m est la monade le test fonctionne et a est finalement ignoré. Dans le cas de PropertyM IO a, vous convertissez le test monadique à un Property en utilisant monadicIO; pour tous les autres monades, vous utilisez monadic à la place (qui prend une fonction à exécuter la monade, quelque chose ne IO pas).

Dans un test monadique, la valeur returned de la monade est ignorée. Pour vérifier une expression, utilisez assert; asserting une valeur fausse échouera le test. Utilisez run pour exécuter le code dans la monade testé.

Il y a d'autres actions monades à votre disposition. Par exemple, pick va générer de nouvelles entrées de test sur un Gen a et pre vérifiera conditions de test. Elles sont utiles si les entrées de test ou conditions préalables elles-mêmes dépendent des valeurs calculées par la monade à l'essai, auquel cas la voie normale de générer des entrées ou le contrôle precontions ne fonctionnera pas.

Voici un exemple de test du code de IO: nous vérifions qu'après avoir écrit quelque chose à un fichier temporaire, on peut lire que les mêmes données en arrière. Pour des fins de démonstration, nous imposons la condition sine qua non pour que nous écrivions au moins un octet dans le fichier. Les deux propriétés de test font la même chose; on utilise pick et pre inutilement tandis que l'autre ne fonctionne pas.

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

Autres conseils

La référence standard pour tester le code monadique est "Test code Monadique avec QuickCheck « . Il montre diverses façons de tester dans le cadre d'une monade tels que IO.

Mais vous devriez vraiment envisager de poser une question plus concrète sur ce qu'il est que vous souhaitez tester.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top