QuickCheck-2.8.1: Automatic testing of Haskell programs

Safe Haskell None 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)
-- ...
`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 FieldsunPropertyM :: (a -> Gen (m Property)) -> Gen (m Property)

Instances

 MonadTrans PropertyM Monad m => Monad (PropertyM m) Functor (PropertyM m) Monad m => Applicative (PropertyM m) MonadIO m => MonadIO (PropertyM m)

# 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.

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

`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`.

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

An alternative to quantification a monadic properties to `pick`, with a notation similar to `forAll`.

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

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 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