2012-10-19 1 views
7

파섹 파서에 대한 테스트를 작성하고 싶습니다.하스켈 - 빠른 검사 덕분에 파섹 테스트

data Event = Event { keyEvent :: String } 
    deriving Show 

parseKey :: Parser Event 
parseKey = do 
      char '<' 
      k <- many1 (letter <|> digit <|> oneOf "_") 
      char '>' 
      return $ Event k 

나는 내가 parse = parse . pretty . parse 속성을 확인해야한다는 것을 알고 여기에 파서와 데이터 구조의 예이다. 그렇다면 을 올바르게 작성해야합니까? 테스트 사례가 올바르지 않습니까? 일반적으로 주어진 BNF에 대한 테스트 케이스를 어떻게 생성해야합니까? 나는 instance Arbitrary에 대해 알고 있지만, 이것에 대해서는별로 도움이되지 않습니다.

이 간단한 파서에 대해 잘 설명 된 발전기 예제를 제공하면 감사하겠습니다.

+2

올바른 테스트 케이스의 경우'id = parse. 꽤 괜찮은거야? (또한,'oneOf "_"= "char '_'') – huon

+0

나는 그것이 충분할 것이라고 생각한다. (또한 첫 번째 버전은 훨씬 더 이상했습니다.) – m0nhawk

+2

@dbaupp : 이것에 대해서는 생각해 보았습니다. 파서에'공백 '이나 건너 뛸 수있는 다른 문자가있을 때 간단한 예제를 생각해 봅시다. 그러면 생성 된 결과가 달라집니다. 그리고 추가로'parse'가 도움이 될 것입니다. – m0nhawk

답변

12

테스트 파서는 완전히 사소한 것은 아닙니다. (모든 테스트와 마찬가지로 문제의 복잡성에 따라)

당신이 할 수있는 한 가지 방법은 모든 유효한 표현식 (또는 구문 분석하려는 내용)을 구성하는 Arbitrary 인스턴스를 작성한 다음 그 결과를 예쁜 것으로 인쇄하고 결과 문자열을 파싱한다면, 당신이 시작한 것과 정확히 똑같은 것을 얻을 수 있습니다. 답이 생겼습니다 무슨 잘못되면

  • :

    는 문제의 몇 가지입니까? 파서 나 프린터?

  • 해석하려는 항목이 선택 사항 인 대괄호와 항목을 포함 할 정도로 복잡하면 선택 사항 인 대괄호없이 또는없이 모두 작동하는지 확인해야합니다. 예쁜 프린터는 보통 한 가지 방법으로 만 수행합니다.

  • 이렇게하면 쓰레기 입력이 실제로 거부되는지 (이상한 것으로 해석되지 않는지) 확인하지 않습니다. 예를 들어, 입력의 에서 발생하는 경우 구문 오류를 자동으로 무시하는 Parsec 파서를 많이 작성했습니다. 일반적으로

, 내가 파서 테스트를 알고있는 유일한 정말 철저한 방법은 많은 손으로 수동 테스트를 많이 작성하는 것입니다. (그리고 틀린 것을 파싱 할 때마다 또 다른 테스트 케이스를 추가하십시오.) 이것은 본질적으로 GHC가 테스트 슈트로하는 일입니다.

물론 파서의 복잡성과 원하는 보증의 정도에 따라 달라집니다 ... JSON을 파싱하는 경우 상당히 쉽게 테스트 할 수 있습니다. Markdown과 같은 것을 파싱한다면 ... 하느님, 당신의 영혼에 자비를 베푸십시오!

+0

관심이 있다면 [XCompose] (http://www.unix.com/man-page/all/5/XCompose/)의 파서를 작성합니다 (여기 [https://github.com/m0nhawk/]). XComposeChecker)가 소스입니다. 그래서 이것을 위해 QuickCheck를 만드는 것이 합리적입니까? 아니면 손으로 쓴 시험이 더 좋을까요? 그리고 두 번째 경우에 어떤 도서관을 제안 할 수 있습니까? – m0nhawk

+0

물론 이러한 것들을 수행 할 수 있습니다. QuickCheck를 사용하여 AST에서 AST 로의 왕복이 작동하는지 확인하고 가장자리 케이스를 확인하기 위해 몇 가지 수동 테스트를 작성하십시오.상당히 작은 문법처럼 보이므로 테스트하기가 너무 어려워서는 안됩니다 ... – MathematicalOrchid