수색…


속성 선언하기

가장 단순한 속성Bool 을 반환하는 함수입니다.

prop_reverseDoesNotChangeLength xs = length (reverse xs) == length xs

프로퍼티는 프로그램의 상위 불변성을 선언합니다. QuickCheck 테스트 러너는 100 개의 임의 입력을 사용하여 함수를 평가하고 결과가 항상 True 인지 확인합니다.

규약에 따라 프로퍼티 인 함수의 이름은 prop_ 시작합니다.

단일 속성 확인

quickCheck 함수는 100 개의 무작위 입력에 대한 속성을 테스트합니다.

ghci> quickCheck prop_reverseDoesNotChangeLength
+++ OK, passed 100 tests.

일부 입력에 대해 속성이 실패하면 quickCheck 가 반례를 출력합니다.

prop_reverseIsAlwaysEmpty xs = reverse xs == []  -- plainly not true for all xs

ghci> quickCheck prop_reverseIsAlwaysEmpty
*** Failed! Falsifiable (after 2 tests):                  
[()]

파일의 모든 속성 검사

quickCheckAll 은 현재 이름이 prop_ 시작하는 파일의 모든 정의를 찾아서 quickCheckAll 하는 Template Haskell 도우미입니다.

{-# LANGUAGE TemplateHaskell #-}

import Test.QuickCheck (quickCheckAll)
import Data.List (sort)

idempotent :: Eq a => (a -> a) -> a -> Bool
idempotent f x = f (f x) == f x

prop_sortIdempotent = idempotent sort

-- does not begin with prop_, will not be picked up by the test runner
sortDoesNotChangeLength xs = length (sort xs) == length xs


return []
main = $quickCheckAll

return [] 행이 필요합니다. Template Haskell이 볼 수있는 선 위에 텍스트로 정의를 만듭니다.

$ runhaskell QuickCheckAllExample.hs
=== prop_sortIdempotent from tree.hs:7 ===
+++ OK, passed 100 tests.

사용자 정의 유형의 데이터를 무작위로 생성

Arbitrary 클래스는 QuickCheck에서 임의로 생성 할 수있는 유형의 클래스입니다.

Arbitrary 의 최소 ​​구현은 Arbitrary 값을 생성하기 위해 Gen 모나드에서 실행되는 arbitrary 메소드입니다.

다음은 비어 있지 않은 목록의 다음 데이터 유형에 대한 Arbitrary 의 인스턴스입니다.

import Test.QuickCheck.Arbitrary (Arbitrary(..))
import Test.QuickCheck.Gen (oneof)
import Control.Applicative ((<$>), (<*>))

data NonEmpty a = End a | Cons a (NonEmpty a)

instance Arbitrary a => Arbitrary (NonEmpty a) where
    arbitrary = oneof [  -- randomly select one of the cases from the list
        End <$> arbitrary,  -- call a's instance of Arbitrary
        Cons <$>
            arbitrary <*>  -- call a's instance of Arbitrary
            arbitrary  -- recursively call NonEmpty's instance of Arbitrary
        ]

함축 (==>)을 사용하여 전제 조건을 사용하여 속성을 확인합니다.

prop_evenNumberPlusOneIsOdd :: Integer -> Property
prop_evenNumberPlusOneIsOdd x = even x ==> odd (x + 1)

전제 조건이 충족되면 속성이 유지되는지 확인하려면 ==> 연산자를 사용할 수 있습니다. 임의 입력이 전제 조건과 일치하지 않는 경우 QuickCheck가 일찍 포기할 수 있습니다.

prop_overlySpecific x y = x == 0 ==> x * y == 0

ghci> quickCheck prop_overlySpecific
*** Gave up! Passed only 31 tests.

테스트 데이터의 크기 제한

무작위 입력이 대개 크기 제한이 없기 때문에 quickcheck를 사용하면 점근 복잡성이 낮은 함수를 테스트하기가 어려울 수 있습니다. 입력의 크기에 상한을 추가함으로써이 값 비싼 함수를 테스트 할 수 있습니다.

import Data.List(permutations)
import Test.QuickCheck

longRunningFunction :: [a] -> Int
longRunningFunction xs = length (permutations xs)

factorial :: Integral a => a -> a
factorial n = product [1..n]

prop_numberOfPermutations xs =
    longRunningFunction xs == factorial (length xs)

ghci> quickCheckWith (stdArgs { maxSize = 10}) prop_numberOfPermutations

사용하여 quickCheckWith 수정 된 버전 stdArgs 우리는 우리의 치환 기능하지 않는 최대 크기 (10)의 목록을 생성 우리 목록을 생성하는 바와 같이,이 수단은,이 경우에, 최대 10 일에 대한 입력의 크기를 제한 할 수있다 이 짧은 목록을 실행하는 데 너무 오래 걸리지 만 우리의 정의가 옳다는 것을 여전히 합리적으로 확신 할 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow