2012-10-10 2 views
16

Angenommen, ich möchte einige Komponententests für die (!!)-Funktion schreiben.Wie kann QuickCheck angewiesen werden, nur gültige Listenindizes für einen Parameter zu generieren?

my_prop xs n = ... 

Ich will n nur gültigen Indizes beschränken, und ich weiß, dass ich so etwas wie

my_prop xs n = (not.null) (drop n xs) ==> ... 

tun konnte, aber das macht es so, dass die überwiegende Mehrheit der erzeugten Fälle ungültig ist und weggeworfen erhält . Gibt es eine Möglichkeit, Dinge einzurichten, so dass QuickCheck die xs Liste zuerst generiert und seinen Wert verwendet, um nur gültige Fälle von n zu generieren?

+1

Erstellen Sie einen neuen Typ mit einer Liste und einem Int mit einer geeigneten Arbitrary-Instanz. –

Antwort

17

Mit forAll können Sie eine generator für n angeben, die von den früheren Argumenten abhängt, z.

my_prop (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \n -> ... 
+0

Ordentlich. Wenn ich zwei Indizes in der Property benötige, wie kann ich ein Gen (Int, Int) an forAll übergeben? Meine aktuelle Lösung verschachtelt fürAlle wie folgt: 'forAll (Indizes xs) $ \ x -> forAll (Indizes xs) $ \ y -> ...' (unter Verwendung der Daniel Fischer-Indexdefinition in einer anderen Antwort). – Arild

10

können Sie einen Generator machen, die gültige Indizes erstellt nur und schreiben Sie Ihre Immobilie wie

import Test.QuickCheck 
import Test.QuickCheck.Gen 
import System.Random 

indices :: [a] -> Gen Int 
indices xs = MkGen $ \sg _ -> fst $ randomR (0, length xs - 1) sg 

my_prop :: [Char] -> Property 
my_prop xs = not (null xs) ==> forAll (indices xs) (\i -> xs !! i /= '0') 

das Int Argument zu beseitigen.

5

Wie von Daniel Wagner vorgeschlagen, ist eine Möglichkeit, meine eigenen Datentyp erstellen und eine Arbitrary Instanz geben.

data ListAndIndex a = ListAndIndex [a] Int deriving (Show) 

instance Arbitrary a => Arbitrary (ListAndIndex a) where 
    arbitrary = do 
    (NonEmpty xs) <- arbitrary 
    n <- elements [0..(length xs - 1)] 
    return $ ListAndIndex xs n 

NonEmpty ist aus einem benutzerdefinierten Typ in Test.QuickCheck.Modifiers für nicht leere Listen zu erzeugen.

Verwandte Themen