2013-08-29 2 views
11

ich QuickCheck bin mit dem folgenden Programm zu testen:Warum gibt QuickCheck auf?

{-# LANGUAGE TemplateHaskell #-} 

import Test.QuickCheck 
import Test.QuickCheck.All 

elementAt :: (Integral b) => [a] -> b -> a 
elementAt [x] _ = x 
elementAt (x:xs) 1 = x 
elementAt (x:xs) b = elementAt xs (b - 1) 

prop_elementAt xs b = length xs > 0 && b >= 0 && b < length xs ==> elementAt xs (b + 1) == xs !! b 

main = $(quickCheckAll) 

Obwohl die Antwort variiert, erhalte ich ständig die Nachricht

*** Gave up! Passed only x tests. 

Ist das etwas, ich besorgt sein sollte? Oder bestimmt die Art der Testeingabe, wie lange QuickCheck laufen soll?

Antwort

17

Die Art und Weise ==> Arbeiten sind zunächst Quick Check Zufallswerte für xs und b generieren wird, dann prüfen, ob das Prädikat length xs > 0 && b >= 0 && b < length xs nur dann erfüllt ist es für die Erfüllbarkeit der Immobilie zu überprüfen.

Da es eine Grenze für die Anzahl der zu generierenden Testfälle gibt, kann es vorkommen, dass das obige Prädikat oft nicht erfüllt wird. So quickcheck gibt auf, bevor genügend gültige Testfälle generiert werden (die das Prädikat erfüllen).

Sie sollten stattdessen Arbitrary Instanz zu einem newtype deklarieren, um nur Testfälle zu erzeugen, die diese Prädikate erfüllen.

{-# LANGUAGE TemplateHaskell #-} 

import Test.QuickCheck 
import Test.QuickCheck.All 

elementAt :: (Integral b) => [a] -> b -> a 
elementAt [x] _ = x 
elementAt (x:xs) 1 = x 
elementAt (x:xs) b = elementAt xs (b - 1) 

prop_elementAt (Foo xs b) = elementAt xs (b + 1) == xs !! b 

data Foo a b = Foo [a] b deriving (Show) 

instance (Integral b, Arbitrary a, Arbitrary b) => Arbitrary (Foo a b) where 
    arbitrary = do 
    as <- listOf1 arbitrary   -- length xs > 0 
    b <- choose (0,length as - 1)  -- b >= 0 and b < length xs 
    return (Foo as $ fromIntegral b) 

main = $(quickCheckAll) 
+0

hatten das gleiche Problem mit der gleichen [99 Frage Haskell Probleme] (http://www.haskell.org/haskellwiki/99_questions/1_to_10) und es scheint gut zu funktionieren. Aber das Ausführen von 'verboseCheck prop_elementAt' für mich gibt endlose Listen zurück, die nur aus dem Element'() 'bestehen, was bedeutet, dass eine Implementierung von 'elementAt (x: xs) _ = x' noch besteht. Irgendeine Idee, wie man eine Liste mit tatsächlichen Elementen darin erzeugt? – ThomasH

+1

Das ist, weil es die falsche Art von prop_elemAt leitet. Geben Sie einen expliziten Typ ein (Beispiel: prop_elementAt :: Foo [Int] Int -> Bool). – Satvik

+0

Das hat es gelöst, danke! – ThomasH