testinghaskellparsecquickcheck

Testing Parsec parsers by generating inputs with QuickCheck


I'd like to write tests for a suite of Parsec parsers. Here's a simple example of a parser I want to test with QuickCheck:

identifier = do
  c <- letter
  cs <- many (alphaNum <|> oneOf identSymbols)
  skipSpaces
  return $ Ident $ c:cs

So, ideally, I'd want QuickCheck to generate valid identifiers and make sure I get the right results back, as well as generating invalid identifiers and making sure they return ParseError. Are there any utilities that would make this sort of thing easier? Is there a way I can "run my parser in reverse", so to speak, to generate such inputs?

In general, what would a good suite of QuickCheck tests for this parser look like? To some extent, it seems like I'd basically have to duplicate the logic of the parser in QuickCheck to achieve a thorough test. Is that really a good idea, or this perhaps a situation where a more traditional tool like HUnit is more suitable than QuickCheck?


Solution

  • In general, the reverse of a parser is a pretty printer, and the reverse of random input to a parser, is random pretty printing of an AST.

    So, follow the usual approach and define an Arbitrary instance for your AST, which drives random well-formed syntax fragments. Mix in some erroneous characters as a wrapper to test for error handling.

    See also: