2014-02-25 12 views
7

ich einen Quick Check Eigenschaft haben, die wie folgt aussieht:Quick Check-Werte gleich

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

Wenn diese Eigenschaft fehlschlägt, wird es ausdrucken, was foo war. Aber ich würde gerne wissen, was fn1 und fn2 zurückgegeben. Und wenn foo groß ist, ist es irgendwie nicht trivial, diese Information von Hand zu erzeugen. (Ie, sitzen Sie dort und geben Sie den riesigen Textkeil in das Windows-Konsolenfenster ein.)

Es ist üblich, Frameworks zu testen, die eine Gleichheitsprüfung haben, und beide Werte ausgibt, wenn die Gleichheit nicht funktioniert halt. Aber ich kann eine solche Funktion für QuickCheck nicht finden ...

Antwort

10

Werfen Sie einen Blick auf Kombinatoren von here. Beispiel: printTestCase ermöglicht das Hinzufügen einer beliebigen Zeichenfolge zur Ausgabe fehlgeschlagener Fälle. Ein kurzes Beispiel:

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

Dies ist _much_ netter als der Hack, den ich versuchte zu verwenden ... – MathematicalOrchid

+1

Dies funktioniert aber veraltet. Stattdessen kann die Verwendung von '===' ausreichen; es [druckt beide Seiten, wenn der Vergleich fehlschlägt] (http://hackage.haskell.org/package/QuickCheck-2.7.3/docs/Test-QuickCheck-Property.html#v:-61--61--61-) . – 9000

0

denke ich, man könnte die folgenden tun, dass fn1 und gn2 Rückkehr unter der Annahme 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

Wow. Genial. Zum Glück ist es nicht erforderlich. – kosmikus

+0

@kosmikus Danke für die Bearbeitung. Ich denke, wir könnten auch einfach schreiben "prop_xx (B1 b1) (B2 b2) = b1 == b2" aber war in diesem Moment nicht sicher. – Ingo

2

Basierend auf der Antwort von Yuuri, ist es das, was ich ging mit :

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

Jetzt kann ich Sachen schreiben wie

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