2017-12-25 9 views
0

하스켈을 배우고 좋은 개발자가되어 단위 테스트를 작성합니다. 다양한 정렬 알고리즘과 해당 테스트를 구현했습니다. 그러나 입력 및 출력이 다양하지 않으므로 입력을 정렬하는 데 사용되는 알고리즘 만 있기 때문에 별도의 테스트가 중복되는 것으로 느낍니다. 여러 다른 단위 테스트 프레임 워크에서 가능한 데이터 기반 테스트 또는 데이터 테이블을 만드는 방법이 있습니까?Hspec을 사용하여 데이터 기반 테스트를 작성하는 방법은 무엇입니까?

module RecursionSpec (main, spec) where 

import Test.Hspec 
import Recursion 

main :: IO() 
main = hspec spec 

spec :: Spec 
spec = do 
    let input = [3, 1, 5, 2, 4] 
     output = [1, 2, 3, 4, 5] 
    describe "bubblesort" $ do 
    it ("sorts " ++ show input) $ do 
     bubblesort input `shouldBe` output 

    describe "mergesort" $ do 
    it ("sorts " ++ show input) $ do 
     mergesort input `shouldBe` output 

    describe "quicksort" $ do 
     it ("sorts " ++ show input) $ do 
     quicksort input `shouldBe` output 

또한 다음과 같은 경고 메시지가 나타납니다.

warning: [-Wtype-defaults] 
    • Defaulting the following constraints to type ‘Integer’ 
     (Show a0) 
      arising from a use of ‘show’ at test/RecursionSpec.hs:14:21-30 
     (Eq a0) 
      arising from a use of ‘shouldBe’ at test/RecursionSpec.hs:15:7-40 
     (Ord a0) 
      arising from a use of ‘bubblesort’ at test/RecursionSpec.hs:15:7-22 
     (Num a0) 
      arising from the literal ‘1’ at test/RecursionSpec.hs:12:17 
     (Num a0) 
      arising from the literal ‘3’ at test/RecursionSpec.hs:11:16 
    • In the second argument of ‘(++)’, namely ‘show input’ 
     In the first argument of ‘it’, namely ‘("sorts " ++ show input)’ 
     In the expression: it ("sorts " ++ show input) 

답변

3

처럼 당신은 고차 함수를 정의 할 수 있습니다

describeSort :: Ord a => String -> ([a] -> [a]) -> [a] -> [a] -> SpecWith b 
describeSort sortName sorter input output = 
    describe sortName $ do 
     it ("sorts " ++ show input) $ do 
     sorter input `shouldBe` output 

그것은 데이터 중심 아니에요,하지만 기본적으로 (내가 구문을 확인할 수 없습니다이 경우에 보일러를 제거 정확히 맞아 , 손에 HSpec을 설치하지 마십시오).

spec :: Spec 
spec = do 
    let input = [3, 1, 5, 2, 4] 
     output = [1, 2, 3, 4, 5] 

    describeSort "bubblesort" bubblesort input output 
    describeSort "mergesort" mergeSort input output 
    describeSort "quicksort" quickSort input output 

하스켈에 특별히 더 많은 데이터 중심 (속성 테스트) 테스트 프레임 워크가 QuickCheck입니다 :

그런 다음으로 테스트를 정의 할 수 있습니다. 함수에 따라 "속성"을 정의하고이를 테스트 할 데이터를 생성 할 수 있습니다.

quickCheck (\xl -> bubblesort xl == sort xl) 
sortData.List 버전

bubblesort 테스트에서 구현입니다 : 예를 들어, 정렬 기능의 빠른 테스트는 다음과 같이 기록 될 수있다. 그런 다음 QuickCheck는 제약 조건에 맞는 100 개의 목록 (Ord 값 목록이어야 함)을 생성하고 발생한 오류를보고합니다.


당신은 아마 명시 적으로 inputoutput의 종류 진술에 의해 그 경고를 해결할 수

:

let input = [3, 1, 5, 2, 4] :: [Integer] 
    output = [1, 2, 3, 4, 5] :: [Integer] 
+0

Upvoted을하지만, 단위 테스트 프레임 워크가 상자 밖으로 제공해야 무엇을 구현하기 위해 더 많은 코드를 작성 내가 찾고 있는게 아니야. 유형을 지정하면 경고가 제거되지만 처음에 왜 나타나는지 이해하고 싶습니다. 'input'은'[Integer]'라는 것이 명백합니다 - 그렇지 않으면 똑똑한 컴파일러는 어떤 문제가 있습니까? –

+0

'빠른 검사'를 통해 더 나은 데이터 중심의 자료를 제공하고, 임의의 테스트 입력을 생성 할 수 있습니다. 그것은 내가 개인적으로 사용하는 것입니다. 오류의 경우 값에 'Integer' 또는'Int' 유형이있을 수 있습니다. – hnefatl

+1

감사합니다. quickcheck을 살펴 보겠습니다. 속성 중심 테스트, 다른 접근 방법 인 것 같습니다. 그리고'[Int]'는'input'과'output'에 대해서도 작동합니다 - 나는 [Int vs Integer] (https://stackoverflow.com/questions/3429291/haskell-int-and-integer)를 잊어 버렸습니다. –