2012-10-14 2 views
9

Ich schrieb einen Quick Check-Eigenschaft für eine Funktion, die zwei sortierten Eingänge in eine sortierte Ausgabe verschmilzt:Conditional Quick Check Eigenschaften

prop_merge xs ys = 
    if (sorted xs && sorted ys) then (sorted (merge xs ys)) else True 

Das heißt, wenn die Eingänge sortiert sind, wird der Ausgang als auch sortiert. Es kann auch geschrieben werden als:

prop_merge xs ys = not(sorted xs && sorted ys) || (sorted (merge xs ys)) 

Aber ich mag keine der beiden Versionen. Gibt es eine schönere Syntax für "bedingte Eigenschaften" in QuickCheck?

Antwort

27

Sie können den ==> Operator eine Booleschen Bedingung Ihre Eigenschaften befestigen:

prop_merge xs ys = (sorted xs && sorted ys) ==> sorted (merge xs ys) 

Dies ist nicht nur eine schönere Syntax, sondern ermöglicht Quick Check zwischen Testfällen zu unterscheiden, wo der Test erfolgreich war und Testfälle was die Voraussetzung nicht erfüllt hat. Im letzteren Fall wird der Test nicht gezählt und QuickCheck generiert neue Eingaben.

In Fällen jedoch, in denen die meisten Eingaben die Bedingung nicht erfüllen, führt dies dazu, dass Ihre Tests entweder langsamer ausgeführt werden, oder wenn genügend Eingaben verworfen werden, gibt QuickCheck schließlich auf. Da eine zufällige Liste unwahrscheinlich ist, sortiert werden, dann ist dies sehr wahrscheinlich, oben am Beispiel geschehen:

> quickCheck (prop_merge :: [Int] -> [Int] -> Property) 
*** Gave up! Passed only 15 tests. 

(Beachten Sie, dass mit Standard-Booleschen Operatoren statt ==> zu verwenden, wird Quick Check über alle Tests steigert weitergegeben werden, wenn die meisten davon waren aufgrund einer fehlgeschlagenen Vorbedingung nutzlos)

Aus diesem Grund ist es im Allgemeinen viel besser, nur die Testfälle zu generieren, die Sie benötigen. In einfachen Fällen enthält das Modul Test.QuickCheck.Modifiers mehrere nützliche neue Typen, die die Art und Weise ändern, wie Eingaben generiert werden. Zum Beispiel generiert der OrderedList Modifikator nur sortierte Listen, so können wir Ihre Immobilie einfach schreiben:

prop_merge (Ordered xs) (Ordered ys) = sorted (merge xs ys) 
+0

Ah, das sieht viel besser aus! – fredoverflow

+2

Ich denke, es wäre nützlich, explizit zu beachten, dass '==>' nicht nur eine schönere Syntax ist, sondern QuickCheck erlaubt, zwischen Testfällen, bei denen der Test erfolgreich war, und Testfällen, die die Voraussetzung nicht erfüllten, zu unterscheiden. Im letzteren Fall wird der Test nicht gezählt und QuickCheck generiert neue Eingaben. Dies ermöglicht QuickCheck, Ihnen die "*** Gave up! Passed nur 15 Tests" zu geben. msgstr "" "Wenn die Vorbedingung über die standardmäßigen booleschen Operatoren ausgedrückt wird, erhöht QuickCheck alle Tests, die durchgeführt wurden, wenn die meisten aufgrund einer fehlgeschlagenen Vorbedingung nutzlos waren. –

+0

@cebewee: Danke für Ihre Vorschläge. Ich habe sie bearbeitet manuell, da sie von den Gutachtern abgelehnt wurden. – hammar