12

QuickCheck次のプログラムをテストするために使用しています。

{-# 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)

反応はさまざまですが、常にメッセージを受け取ります

*** Gave up! Passed only x tests.

これは私が心配すべきことですか?または、テスト入力の性質によって、QuickCheck が実行される時間が決まりますか?

4

1 に答える 1

18

仕組み==>としては、最初に quickcheck が と のランダムな値を生成しxsb述語length xs > 0 && b >= 0 && b < length xsが満たされているかどうかのみをチェックしてから、プロパティの充足可能性をチェックします。

生成されるテスト ケースの数には制限があるため、多くの場合、上記の述語が満たされないことがあります。したがって、十分な有効なテストケースを生成する前に (述語を満たす)、quickcheck はあきらめます。

代わりにインスタンスを newtype に宣言Arbitraryして、これらの述語を満たすテストケースのみを生成する必要があります。

{-# 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)
于 2013-08-29T05:27:48.207 に答える