Haskell Language
빠른 확인
수색…
속성 선언하기
가장 단순한 속성 은 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 일에 대한 입력의 크기를 제한 할 수있다 이 짧은 목록을 실행하는 데 너무 오래 걸리지 만 우리의 정의가 옳다는 것을 여전히 합리적으로 확신 할 수 있습니다.