2014-02-25 114 views
7

我有一个快速检查属性,它看起来像这样:快速检查值等于

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

如果该物业的失败,它会打印出什么foo了。但我真的很想知道什么fn1fn2返回。如果foo很大,那么手工生成这些信息也是不重要的。 (即,坐在那里,手动键入打印到Windows控制台窗口的大量文本)。

测试框架有一个比较相等的东西是常见的,如果相等没有,则打印出两个值保持。但我似乎无法为QuickCheck找到这样的功能...

回答

10

看看here的组合器。例如,printTestCase允许将任意字符串添加到失败案例的输出中。一个简单的例子:

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

这比我试图使用的黑客更好... – MathematicalOrchid

+1

这个作品,但不推荐使用。相反,使用'==='可能就够了;它[在比较失败时打印双方](http://hackage.haskell.org/package/QuickCheck-2.7.3/docs/Test-QuickCheck-Property.html#v:-61--61--61-) 。 – 9000

0

我觉得一个可以做到以下几点,假设fn1gn2回报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 
+0

哇。巧妙。幸运的是,这不是必需的。 – kosmikus

+0

@kosmikus感谢您的编辑。我想我们也可以只写'prop_xx(B1 b1)(B2 b2)= b1 == b2',但当时不确定。 – Ingo

2

基于从Yuuri答案,这就是我与去:

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

现在我可以写东西了像

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