QuickCheck is a Haskell library for property-based testing: write a property that should hold for all inputs, then check it against automatically generated cases. It is especially useful for pure functions, where correctness can be expressed by comparing outputs for the same inputs. Add QuickCheck >= 2.0 to package.yaml; Stack resolves the dependency when building or starting the REPL. section 9.0 section 9.2.1 section 9.3
ghci> import Test.QuickCheck ghci> prop_rot13Symm s = s == rot13 (rot13 s) ghci> :t prop_rot13Symm prop_rot13Symm :: String -> Bool ghci> quickCheck prop_rot13Symm +++ OK, passed 100 tests.
A property can be an ordinary function returning Bool. quickCheck turns checking it into an IO action and generates String inputs automatically. section 9.3.1
Use the prop_ prefix for properties. A passing result means the generated tests did not falsify the property; it is not a proof. When a property fails, QuickCheck reports a counterexample and shrinks it to a simpler failing input, making a bug easier to inspect. section 9.3.1 section 9.4.3
QuickCheck provides the pieces needed to tailor test data and test behavior:
- Generate data with Gen and generate. Build generators with choose, elements, oneof, listOf, vectorOf, shuffle, and suchThat. section 9.4.1
- Use arbitrary when an Arbitrary instance supplies generation for a type; define arbitrary and shrink for custom types such as associative maps. section 9.4.1 section 9.4.3
- Use forAll to connect a custom generator to a property, such as generating a nonempty alphabet, a bounded rotation amount, and a character from that alphabet. section 9.4.1
- Inspect generated cases with verbose, summarize them with collect or label, and require distributions with cover. section 9.5.1
- Add preconditions with ==>. Check discarded cases, since narrow preconditions can leave too little useful test data. section 9.5.1
Diagnosing a misleading sorting test
A sorting property can appear to pass even for id when GHC defaults the element type to (). verbose exposes the trivial inputs. Give the property an explicit type such as [Int] -> Bool, then use collect or label to see empty lists and cover to require enough non-trivial cases. section 9.5 section 9.5.1
For a Stack test suite, place test code under test and run stack test. quickCheckAll uses Template Haskell to find prop_-prefixed properties in a module; combine suite results in Main and return a success or failure exit code. section 9.5.3 section 9.6


