Safe Haskell | None |
---|---|
Language | Haskell98 |
This module includes almost everything you need to get started writing property tests with Hedgehog.
It is designed to be used alongside Hedgehog.Gen and Hedgehog.Range, which should be imported qualified. You also need to enable Template Haskell so the Hedgehog test runner can find your properties.
{-# LANGUAGE TemplateHaskell #-} import Hedgehog import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range
Once you have your imports set up, you can write a simple property:
prop_reverse :: Property prop_reverse = property $ do xs <- forAll $ Gen.list (Range.linear 0 100) Gen.alpha reverse (reverse xs) === xs
And add the Template Haskell splice which will discover your properties:
tests :: IO Bool tests = checkParallel $$(discover)
If you prefer to avoid macros, you can specify the group of properties to run manually instead:
{-# LANGUAGE OverloadedStrings #-} tests :: IO Bool tests = checkParallel $ Group "Test.Example" [ ("prop_reverse", prop_reverse) ]
You can then load the module in GHCi, and run it:
λ tests ━━━ Test.Example ━━━ ✓ prop_reverse passed 100 tests.
- data Group = Group {
- groupName :: !GroupName
- groupProperties :: ![(PropertyName, Property)]
- data GroupName
- data Property
- data PropertyName
- data Test m a
- data TestLimit
- data DiscardLimit
- data ShrinkLimit
- data Gen m a
- data Range a
- newtype Size = Size {}
- data Seed = Seed {}
- property :: Test IO () -> Property
- withTests :: TestLimit -> Property -> Property
- withDiscards :: DiscardLimit -> Property -> Property
- withShrinks :: ShrinkLimit -> Property -> Property
- check :: MonadIO m => Property -> m Bool
- recheck :: MonadIO m => Size -> Seed -> Property -> m ()
- discover :: TExpQ Group
- checkParallel :: MonadIO m => Group -> m Bool
- checkSequential :: MonadIO m => Group -> m Bool
- forAll :: (Monad m, Show a, HasCallStack) => Gen m a -> Test m a
- forAllWith :: (Monad m, HasCallStack) => (a -> String) -> Gen m a -> Test m a
- annotate :: (Monad m, HasCallStack) => String -> Test m ()
- annotateShow :: (Monad m, Show a, HasCallStack) => a -> Test m ()
- footnote :: Monad m => String -> Test m ()
- footnoteShow :: (Monad m, Show a) => a -> Test m ()
- success :: Monad m => Test m ()
- discard :: Monad m => Test m a
- failure :: (Monad m, HasCallStack) => Test m a
- assert :: (Monad m, HasCallStack) => Bool -> Test m ()
- (===) :: (Monad m, Eq a, Show a, HasCallStack) => a -> a -> Test m ()
- liftCatch :: (MonadCatch m, HasCallStack) => m a -> Test m a
- liftCatchIO :: (MonadIO m, HasCallStack) => IO a -> Test m a
- liftEither :: (Monad m, Show x, HasCallStack) => Either x a -> Test m a
- liftExceptT :: (Monad m, Show x, HasCallStack) => ExceptT x m a -> Test m a
- withCatch :: (MonadCatch m, HasCallStack) => Test m a -> Test m a
- withExceptT :: (Monad m, Show x, HasCallStack) => Test (ExceptT x m) a -> Test m a
- withResourceT :: MonadResourceBase m => Test (ResourceT m) a -> Test m a
- tripping :: HasCallStack => Applicative f => Monad m => Show b => Show (f a) => Eq (f a) => a -> (a -> b) -> (b -> f a) -> Test m ()
- data Command n m state = (HTraversable input, Show (input Symbolic), Typeable output) => Command {
- commandGen :: state Symbolic -> Maybe (Gen n (input Symbolic))
- commandExecute :: input Concrete -> Test m output
- commandCallbacks :: [Callback input output m state]
- data Callback input output m state
- data Action m state
- executeSequential :: forall m state. (HasCallStack, MonadCatch m) => (forall v. state v) -> [Action m state] -> Test m ()
- newtype Concrete a where
- data Symbolic a where
- data Var
- newtype Opaque a = Opaque {
- unOpaque :: a
- distribute :: (Distributive g, Transformer f g m) => g (f m) a -> f (g m) a
- class HTraversable t where
- class Eq1 f
- eq1 :: (Eq1 f, Eq a) => f a -> f a -> Bool
- class Eq1 f => Ord1 f
- compare1 :: (Ord1 f, Ord a) => f a -> f a -> Ordering
- class Show1 f
- showsPrec1 :: (Show1 f, Show a) => Int -> f a -> ShowS
Documentation
A named collection of property tests.
Group | |
|
The name of a group of properties.
A property test to check, along with some configurable limits like how many times to run the test.
data PropertyName Source #
The name of a property.
A property test.
MonadTrans Test Source # | |
Distributive Test Source # | |
MonadBase b m => MonadBase b (Test m) Source # | |
MonadError e m => MonadError e (Test m) Source # | |
MonadReader r m => MonadReader r (Test m) Source # | |
MonadState s m => MonadState s (Test m) Source # | |
Monad m => Monad (Test m) Source # | |
Functor m => Functor (Test m) Source # | |
Monad m => Applicative (Test m) Source # | |
MonadIO m => MonadIO (Test m) Source # | |
Monad m => Alternative (Test m) Source # | |
Monad m => MonadPlus (Test m) Source # | |
MonadCatch m => MonadCatch (Test m) Source # | |
MonadThrow m => MonadThrow (Test m) Source # | |
PrimMonad m => PrimMonad (Test m) Source # | |
MonadResource m => MonadResource (Test m) Source # | |
MFunctor * Test Source # | |
type Transformer t Test m Source # | |
type PrimState (Test m) Source # | |
The number of successful tests that need to be run before a property test is considered successful.
data DiscardLimit Source #
The number of discards to allow before giving up.
data ShrinkLimit Source #
The number of shrinks to try before giving up on shrinking.
Generator for random values of a
.
MMonad Gen Source # | |
MonadTrans Gen Source # | |
Distributive Gen Source # | |
MonadBase b m => MonadBase b (Gen m) Source # | |
MonadError e m => MonadError e (Gen m) Source # | |
MonadReader r m => MonadReader r (Gen m) Source # | |
MonadState s m => MonadState s (Gen m) Source # | |
MonadWriter w m => MonadWriter w (Gen m) Source # | |
Monad m => Monad (Gen m) Source # | |
Functor m => Functor (Gen m) Source # | |
Monad m => Applicative (Gen m) Source # | |
MonadIO m => MonadIO (Gen m) Source # | |
Monad m => Alternative (Gen m) Source # | |
Monad m => MonadPlus (Gen m) Source # | |
MonadCatch m => MonadCatch (Gen m) Source # | |
MonadThrow m => MonadThrow (Gen m) Source # | |
PrimMonad m => PrimMonad (Gen m) Source # | |
MonadResource m => MonadResource (Gen m) Source # | |
MFunctor * Gen Source # | |
type Transformer t Gen m Source # | |
type PrimState (Gen m) Source # | |
A range describes the bounds of a number to generate, which may or may not
be dependent on a Size
.
Tests are parameterized by the size of the randomly-generated data, the meaning of which depends on the particular generator used.
A splittable random number generator.
Property
withTests :: TestLimit -> Property -> Property Source #
Set the number times a property should be executed before it is considered successful.
withDiscards :: DiscardLimit -> Property -> Property Source #
Set the number times a property is allowed to discard before the test runner gives up.
withShrinks :: ShrinkLimit -> Property -> Property Source #
Set the number times a property is allowed to shrink before the test runner gives up and prints the counterexample.
recheck :: MonadIO m => Size -> Seed -> Property -> m () Source #
Check a property using a specific size and seed.
discover :: TExpQ Group Source #
Discover all the properties in a module.
Functions starting with prop_
are assumed to be properties.
checkParallel :: MonadIO m => Group -> m Bool Source #
Check a group of properties in parallel.
Warning: although this check function runs tests faster than
checkSequential
, it should be noted that it may cause problems with
properties that are not self-contained. For example, if you have a group
of tests which all use the same database table, you may find that they
interfere with each other when being run in parallel.
Using Template Haskell for property discovery:
tests :: IO Bool tests = checkParallel $$(discover)
With manually specified properties:
tests :: IO Bool tests = checkParallel $ Group "Test.Example" [ ("prop_reverse", prop_reverse) ]
checkSequential :: MonadIO m => Group -> m Bool Source #
Check a group of properties sequentially.
Using Template Haskell for property discovery:
tests :: IO Bool tests = checkSequential $$(discover)
With manually specified properties:
tests :: IO Bool tests = checkSequential $ Group "Test.Example" [ ("prop_reverse", prop_reverse) ]
Test
forAll :: (Monad m, Show a, HasCallStack) => Gen m a -> Test m a Source #
Generates a random input for the test by running the provided generator.
forAllWith :: (Monad m, HasCallStack) => (a -> String) -> Gen m a -> Test m a Source #
annotate :: (Monad m, HasCallStack) => String -> Test m () Source #
Annotates the source code with a message that might be useful for debugging a test failure.
annotateShow :: (Monad m, Show a, HasCallStack) => a -> Test m () Source #
Annotates the source code with a value that might be useful for debugging a test failure.
footnote :: Monad m => String -> Test m () Source #
Logs a message to be displayed as additional information in the footer of the failure report.
footnoteShow :: (Monad m, Show a) => a -> Test m () Source #
Logs a value to be displayed as additional information in the footer of the failure report.
assert :: (Monad m, HasCallStack) => Bool -> Test m () Source #
Fails the test if the condition provided is False
.
(===) :: (Monad m, Eq a, Show a, HasCallStack) => a -> a -> Test m () infix 4 Source #
Fails the test if the two arguments provided are not equal.
liftCatch :: (MonadCatch m, HasCallStack) => m a -> Test m a Source #
Fails the test if the action throws an exception.
/The benefit of using this over lift
is that the location of the
exception will be shown in the output./
liftCatchIO :: (MonadIO m, HasCallStack) => IO a -> Test m a Source #
Fails the test if the action throws an exception.
/The benefit of using this over liftIO
is that the location of the
exception will be shown in the output./
liftEither :: (Monad m, Show x, HasCallStack) => Either x a -> Test m a Source #
liftExceptT :: (Monad m, Show x, HasCallStack) => ExceptT x m a -> Test m a Source #
withCatch :: (MonadCatch m, HasCallStack) => Test m a -> Test m a Source #
Fails the test if the action throws an exception.
/The benefit of using this over simply letting the exception bubble up is
that the location of the closest withCatch
will be shown in the output./
withExceptT :: (Monad m, Show x, HasCallStack) => Test (ExceptT x m) a -> Test m a Source #
withResourceT :: MonadResourceBase m => Test (ResourceT m) a -> Test m a Source #
tripping :: HasCallStack => Applicative f => Monad m => Show b => Show (f a) => Eq (f a) => a -> (a -> b) -> (b -> f a) -> Test m () Source #
Test that a pair of encode / decode functions are compatible.
Abstract State Machine
data Command n m state Source #
The specification for the expected behaviour of an Action
.
(HTraversable input, Show (input Symbolic), Typeable output) => Command | |
|
data Callback input output m state Source #
Optional command configuration.
Require (state Symbolic -> input Symbolic -> Bool) | A pre-condition for a command that must be verified before the command can be executed. This is mainly used during shrinking to ensure that it is still OK to run a command despite the fact that some previously executed commands may have been removed from the sequence. |
Update (forall v. Ord1 v => state v -> input v -> v output -> state v) | Updates the model state, given the input and output of the command. Note
that this function is polymorphic in the type of values. This is because
it must work over |
Ensure (state Concrete -> input Concrete -> output -> Test m ()) | A post-condition for a command that must be verified for the command to be considered a success. |
An instantiation of a Command
which can be executed, and its effect
evaluated.
executeSequential :: forall m state. (HasCallStack, MonadCatch m) => (forall v. state v) -> [Action m state] -> Test m () Source #
Executes a list of actions sequentially, verifying that all post-conditions are met and no exceptions are thrown.
To generate a sequence of actions to execute, see the
actions
combinator in the Hedgehog.Gen module.
Symbolic variable names.
Opaque values.
Useful if you want to put something without a Show
instance inside
something which you'd like to be able to display.
For example:
data Ref v = Ref (v (Opaque (IORef Int)))
Transformers
distribute :: (Distributive g, Transformer f g m) => g (f m) a -> f (g m) a Source #
Distribute one monad transformer over another.
Functors
class HTraversable t where Source #
Higher-order traversable functors.
htraverse :: Applicative f => (forall a. g a -> f (h a)) -> t g -> f (t h) Source #
Lifting of the Eq
class to unary type constructors.
Eq1 [] | |
Eq1 Maybe | |
Eq1 Identity | |
Eq1 Concrete # | |
Eq1 Symbolic # | |
Eq a => Eq1 (Either a) | |
Eq a => Eq1 ((,) a) | |
Eq1 (Proxy *) | Since: 4.9.0.0 |
Eq1 m => Eq1 (ListT m) | |
Eq1 m => Eq1 (MaybeT m) | |
Eq a => Eq1 (Const * a) | |
(Eq w, Eq1 m) => Eq1 (WriterT w m) | |
(Eq e, Eq1 m) => Eq1 (ExceptT e m) | |
(Eq e, Eq1 m) => Eq1 (ErrorT e m) | |
Eq1 f => Eq1 (IdentityT * f) | |
(Eq w, Eq1 m) => Eq1 (WriterT w m) | |
(Eq1 f, Eq1 g) => Eq1 (Product * f g) | |
(Eq1 f, Eq1 g) => Eq1 (Compose * * f g) | |
eq1 :: (Eq1 f, Eq a) => f a -> f a -> Bool #
Lift the standard (
function through the type constructor.==
)
Lifting of the Ord
class to unary type constructors.
Ord1 [] | |
Ord1 Maybe | |
Ord1 Identity | |
Ord1 Concrete # | |
Ord1 Symbolic # | |
Ord a => Ord1 (Either a) | |
Ord a => Ord1 ((,) a) | |
Ord1 (Proxy *) | Since: 4.9.0.0 |
Ord1 m => Ord1 (ListT m) | |
Ord1 m => Ord1 (MaybeT m) | |
Ord a => Ord1 (Const * a) | |
(Ord w, Ord1 m) => Ord1 (WriterT w m) | |
(Ord e, Ord1 m) => Ord1 (ExceptT e m) | |
(Ord e, Ord1 m) => Ord1 (ErrorT e m) | |
Ord1 f => Ord1 (IdentityT * f) | |
(Ord w, Ord1 m) => Ord1 (WriterT w m) | |
(Ord1 f, Ord1 g) => Ord1 (Product * f g) | |
(Ord1 f, Ord1 g) => Ord1 (Compose * * f g) | |
compare1 :: (Ord1 f, Ord a) => f a -> f a -> Ordering #
Lift the standard compare
function through the type constructor.
Lifting of the Show
class to unary type constructors.
Show1 [] | |
Show1 Maybe | |
Show1 Identity | |
Show1 Concrete # | |
Show1 Symbolic # | |
Show a => Show1 (Either a) | |
Show a => Show1 ((,) a) | |
Show1 (Proxy *) | Since: 4.9.0.0 |
Show1 m => Show1 (ListT m) | |
Show1 m => Show1 (MaybeT m) | |
Show1 m => Show1 (Node m) # | |
Show1 m => Show1 (Tree m) # | |
Show a => Show1 (Const * a) | |
(Show w, Show1 m) => Show1 (WriterT w m) | |
(Show e, Show1 m) => Show1 (ExceptT e m) | |
(Show e, Show1 m) => Show1 (ErrorT e m) | |
Show1 f => Show1 (IdentityT * f) | |
(Show w, Show1 m) => Show1 (WriterT w m) | |
(Show1 f, Show1 g) => Show1 (Product * f g) | |
(Show1 f, Show1 g) => Show1 (Compose * * f g) | |