7
votes

I have a QuickCheck property that looks like this:

prop42 :: Foo -> Bool
prop42 foo = fn1 foo == fn2 foo

If this property fails, it will print out what foo was. But I'd really like to know what fn1 and fn2 returned. And if foo is large, it's kinda non-trivial to generate this information by hand. (I.e., sit there and manually type in the huge wedge of text printed to the Windows console window.)

It's common for testing frameworks to have a thing that compares for equality, and prints out both values if equality didn't hold. But I can't seem to find such a function for QuickCheck...

3

3 Answers

10
votes

Take a look at combinators from here. For example, printTestCase allows to add an arbitrary string to the output of failing cases. A quick example:

prop x = let f = sin x
    in printTestCase ("Should be at least " ++ show f) $ x >= sin x
$> quickCheck prop
*** Failed! Falsifiable (after 2 tests and 1 shrink): 
-1.0
Should be at least -0.8414709848078965
2
votes

Based on the answer from Yuuri, this is what I went with:

(?==?) :: (Eq x, Show x) => x -> x -> Property
x ?==? y =
  printTestCase ("Left:  " ++ show x) $
  printTestCase ("Right: " ++ show y) $
  x == y

Now I can write things like

prop42 :: Foo -> Prop
prop42 foo = fn1 foo ?==? fn2 foo
0
votes

I think one could do the following, assuming that fn1 and gn2 return Bar:

newtype Bar1 = B1 Bar deriving Show
newtype Bar2 = B2 Bar deriving Show
instance Arbitrary Bar1 where
   arbitrary = arbitrary >>= return . B1 . fn1
instance Arbitrary Bar2 where
   arbitrary = arbitrary >>= return . B2 . fn2

prop_xx = forAll arbitrary $ \(B1 b1) ->
             forAll arbitrary $ \(B2 b2) ->
                b1 == b2