Running properties that do not draw any random values only once

Nick Smallbone nicsma at chalmers.se
Mon Apr 16 00:21:19 BST 2012


Hi Simon,

On 12 April 2012 19:49, Simon Hengel <sol at typeful.net> wrote:
> I think it is possible to define a more general variant of `once` with
> what we already got.
>
>    newtype Once a = Once {unOnce :: a}
>
>    instance Testable a => Testable (Once a) where
>      property     = property . unOnce
>      exhaustive _ = True

Actually, this is what I tried at first! The problem is that it won't work to do
   prop_foo x y z = Once $ ...
since quickCheck prop_foo will use the Testable (a -> b) instance,
which has exhaustive _ = False. Rather, you would have to do
   prop_foo = Once $ \x y z -> ...
so it'd be a nasty trap for users. So the 'exhaustive' thing is indeed
quite cosmetic.

> I'm not asking you to add this to QuickCheck!  I'm just saying that
> `exhaustive` seems to be flexible enough.  I could easily define `once`
> myself; but I will most likely experiment with a different set of
> combinators.

There is definitely room for improvement here, so do let me know how
it goes and if you need anything else! I would be happy to have an
excuse to make QuickCheck's testing loop easier to control.

I am hoping that 'once' is useful as a general mechanism for stopping
testing early, since it really means "do not run any tests after this
one" rather than "run only one test in total". For example, you can
implement a conditional early exit by
   stopIf :: Testable a => Bool -> a -> Property
   stopIf b p
      | b = once p
      | otherwise = p
which stops testing if 'b' is True.

Nick



More information about the QuickCheck mailing list