| Safe Haskell | Safe |
|---|---|
| Language | Haskell98 |
Test.QuickCheck.Monadic
Description
Allows testing of monadic values. Will generally follow this form:
prop_monadic a b =monadicIO$ do a' <-run(f a) b' <-run(f b) -- ...assertsomeBoolean
Example using the FACTOR(1) command-line utility:
import System.Process import Test.QuickCheck import Test.QuickCheck.Monadic -- $ factor 16 -- 16: 2 2 2 2 factor :: Integer -> IO [Integer] factor n = parse `fmap`readProcess"factor" [show n] "" where parse :: String -> [Integer] parse = map read . tail . words prop_factor :: Positive Integer -> Property prop_factor (Positiven) =monadicIO$ do factors <-run(factor n)assert(product factors == n)
>>>quickCheck prop_factor+++ OK, passed 100 tests.
See the paper "Testing Monadic Code with QuickCheck".
- newtype PropertyM m a = MkPropertyM {
- unPropertyM :: (a -> Gen (m Property)) -> Gen (m Property)
- run :: Monad m => m a -> PropertyM m a
- assert :: Monad m => Bool -> PropertyM m ()
- pre :: Monad m => Bool -> PropertyM m ()
- wp :: Monad m => m a -> (a -> PropertyM m b) -> PropertyM m b
- pick :: (Monad m, Show a) => Gen a -> PropertyM m a
- forAllM :: (Monad m, Show a) => Gen a -> (a -> PropertyM m b) -> PropertyM m b
- monitor :: Monad m => (Property -> Property) -> PropertyM m ()
- stop :: (Testable prop, Monad m) => prop -> PropertyM m a
- monadic :: Monad m => (m Property -> Property) -> PropertyM m a -> Property
- monadic' :: Monad m => PropertyM m a -> Gen (m Property)
- monadicIO :: PropertyM IO a -> Property
- monadicST :: (forall s. PropertyM (ST s) a) -> Property
- runSTGen :: (forall s. Gen (ST s a)) -> Gen a
Property monad
newtype PropertyM m a
The property monad is really a monad transformer that can contain
monadic computations in the monad m it is parameterized by:
m- them-computations that may be performed withinPropertyM
Elements of PropertyM m a may mix property operations and m-computations.
Constructors
| MkPropertyM | |
Fields
| |
Monadic specification combinators
run :: Monad m => m a -> PropertyM m a
The lifting operation of the property monad. Allows embedding
monadic/IO-actions in properties:
log :: Int -> IO () prop_foo n = monadicIO $ do run (log n) -- ...
assert :: Monad m => Bool -> PropertyM m ()
Allows embedding non-monadic properties into monadic ones.
pre :: Monad m => Bool -> PropertyM m ()
Tests preconditions. Unlike assert this does not cause the
property to fail, rather it discards them just like using the
implication combinator ==>.
This allows representing the Hoare triple
{p} x ← e{q}as
pre p x <- run e assert q
pick :: (Monad m, Show a) => Gen a -> PropertyM m a
Quantification in a monadic property, fits better with
do-notation than forAllM.
monitor :: Monad m => (Property -> Property) -> PropertyM m ()
Allows making observations about the test data:
monitor (collect e)
collects the distribution of value of e.
monitor (counterexample "Failure!")
Adds "Failure!" to the counterexamples.
Run functions
monadicIO :: PropertyM IO a -> Property
Runs the property monad for IO-computations.
prop_cat msg = monadicIO $ do (exitCode, stdout, _) <- run (readProcessWithExitCode"cat" [] msg) pre (ExitSuccess== exitCode) assert (stdout == msg)
>>>quickCheck prop_cat+++ OK, passed 100 tests.
monadicST :: (forall s. PropertyM (ST s) a) -> Property
Runs the property monad for ST-computations.
-- Your mutable sorting algorithm here sortST :: Ord a => [a] ->STs (MVector s a) sortST =thaw.fromList.sortprop_sortST xs = monadicST $ do sorted <- run (freeze=<< sortST xs) assert (toListsorted == sort xs)
>>>quickCheck prop_sortST+++ OK, passed 100 tests.