Testing individual functions for their natural properties is one of the basic building blocks that guides development of large systems in Haskell. We’ll look now at a more complicated scenario: taking the pretty-printing library developed in earlier chapters and building a test suite for it.
Recall that the pretty printer is built around the Doc, an algebraic data type that represents well-formed documents:
-- file: ch11/Prettify2.hs data Doc = Empty | Char Char | Text String | Line | Concat Doc Doc | Union Doc Doc deriving (Show,Eq)
The library itself is implemented as a set of functions that build and transform values of this document type, before finally rendering the finished document to a string.
QuickCheck encourages an approach to testing where the developer specifies
invariants that should hold for any data we can throw at the code. To
test the pretty-printing library, then, we’ll need a source of input
data. To do this, we take advantage of the small combinator suite for
building random data that QuickCheck provides via the
Arbitrary class. The class provides a function,
generate data of each type. With it, we can define our data generator
for our custom data types:
-- file: ch11/Arbitrary.hs class Arbitrary a where arbitrary :: Gen a
One thing to notice is that the generators run in a Gen environment, indicated by the type. This is a simple state-passing monad that is used to hide the random ...