QuickCheck-2.14.3: Automatic testing of Haskell programs
Safe HaskellSafe
LanguageHaskell2010

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) -- ... assert someBoolean 

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 (Positive n) = 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".

Synopsis

Property monad

newtype PropertyM m a Source #

The property monad is really a monad transformer that can contain monadic computations in the monad m it is parameterized by:

  • m - the m-computations that may be performed within PropertyM

Elements of PropertyM m a may mix property operations and m-computations.

Constructors

MkPropertyM 

Fields

Instances

Instances details
MonadTrans PropertyM Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

lift :: Monad m => m a -> PropertyM m a #

Monad m => MonadFail (PropertyM m) Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

fail :: String -> PropertyM m a #

MonadIO m => MonadIO (PropertyM m) Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

liftIO :: IO a -> PropertyM m a #

Applicative (PropertyM m) Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

pure :: a -> PropertyM m a #

(<*>) :: PropertyM m (a -> b) -> PropertyM m a -> PropertyM m b #

liftA2 :: (a -> b -> c) -> PropertyM m a -> PropertyM m b -> PropertyM m c #

(*>) :: PropertyM m a -> PropertyM m b -> PropertyM m b #

(<*) :: PropertyM m a -> PropertyM m b -> PropertyM m a #

Functor (PropertyM m) Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

fmap :: (a -> b) -> PropertyM m a -> PropertyM m b #

(<$) :: a -> PropertyM m b -> PropertyM m a #

Monad m => Monad (PropertyM m) Source # 
Instance details

Defined in Test.QuickCheck.Monadic

Methods

(>>=) :: PropertyM m a -> (a -> PropertyM m b) -> PropertyM m b #

(>>) :: PropertyM m a -> PropertyM m b -> PropertyM m b #

return :: a -> PropertyM m a #

Monadic specification combinators

run :: Monad m => m a -> PropertyM m a Source #

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 () Source #

Allows embedding non-monadic properties into monadic ones.

assertWith :: Monad m => Bool -> String -> PropertyM m () Source #

Like assert but allows caller to specify an explicit message to show on failure.

Example:

do assertWith True "My first predicate." assertWith False "My other predicate." ... 
Assertion failed (after 2 tests): Passed: My first predicate Failed: My other predicate 

pre :: Monad m => Bool -> PropertyM m () Source #

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 

wp :: Monad m => m a -> (a -> PropertyM m b) -> PropertyM m b Source #

The weakest precondition

wp(x ← e, p)

can be expressed as in code as wp e (\x -> p).

pick :: (Monad m, Show a) => Gen a -> PropertyM m a Source #

Quantification in a monadic property, fits better with do-notation than forAllM. Note: values generated by pick do not shrink.

forAllM :: (Monad m, Show a) => Gen a -> (a -> PropertyM m b) -> PropertyM m b Source #

Quantification in monadic properties to pick, with a notation similar to forAll. Note: values generated by forAllM do not shrink.

monitor :: Monad m => (Property -> Property) -> PropertyM m () Source #

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.

stop :: (Testable prop, Monad m) => prop -> PropertyM m a Source #

Run functions

monadicIO :: Testable a => PropertyM IO a -> Property Source #

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 :: Testable a => (forall s. PropertyM (ST s) a) -> Property Source #

Runs the property monad for ST-computations.

-- Your mutable sorting algorithm here sortST :: Ord a => [a] -> ST s (MVector s a) sortST = thaw . fromList . sort prop_sortST xs = monadicST $ do sorted <- run (freeze =<< sortST xs) assert (toList sorted == sort xs) 
>>> quickCheck prop_sortST +++ OK, passed 100 tests. 

runSTGen :: (forall s. Gen (ST s a)) -> Gen a Source #