2012-10-10 7 views
16

(!!) 함수에 대한 단위 테스트를 작성하고 싶습니다.QuickCheck가 매개 변수의 유효한 목록 색인 만 생성하도록 지시하는 방법은 무엇입니까?

my_prop xs n = ... 

내가에만 유효 인덱스 n을 제한 할 그리고 내가

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

처럼 뭔가를 할 수 알고하지만 생성 된 대부분의 경우는 무효 멀리 던져 있도록이 그것을 만든다 . QuickCheck가 xs 목록을 먼저 생성하고 해당 값을 n의 유효한 경우 만 생성하도록 사용하도록 설정하는 방법이 있습니까?

+1

목록을 포함하는 새로운 유형과 적절한 '임의'인스턴스가있는 'Int'를 만듭니다. –

답변

17

forAll을 사용하면 n에 대해 generator을 지정할 수 있습니다. 이는 이전 인수에 따라 다릅니다. 예 :

+0

깔끔한 만일 내가 두 가지 색인을 필요로한다면, Gen (Int, Int)를 forAll에 어떻게 전달할 수 있습니까? 현재 해결책은 ForAll (indices xs) $ \ x -> forAll (indices xs) $ \ y -> ...'와 같은 forAll 중첩입니다 (Daniel Fischer의 색인 정의를 사용하여 다른 답변에 표시됨). – Arild

10

은 당신은 유효한 인덱스를 생성하는 발전기을하고 Int 인수를 제거

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') 

처럼 속성을 작성할 수 있습니다.

5

Daniel Wagner가 제안한 것처럼, 내 자신의 데이터 형식을 만들어서 Arbitrary 인스턴스를 부여 할 가능성이 있습니다.

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이 아닌 빈 목록을 생성 Test.QuickCheck.Modifiers에서 사용자 지정 유형에서입니다.