Doctest: Test interactive Haskell examples
doctest is available from
Install it, by typing:
cabal install doctest
Make sure that Cabal's
bindir is on your
On Mac OS X:
On Windows it's
C:\Documents And Settings\user\Application Data\cabal\bin.
For more information, see the section on paths in the Cabal User Guide.
Below is a small Haskell module. The module contains a Haddock comment with some examples of interaction. The examples demonstrate how the module is supposed to be used.
module Fib where -- | Compute Fibonacci numbers -- -- Examples: -- -- >>> fib 10 -- 55 -- -- >>> fib 5 -- 5 fib :: Int -> Int fib 0 = 0 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2)
(A comment line starting with
>>> denotes an expression.
All comment lines following an expression denote the result of that expression.
Result is defined by what an
REPL (e.g. ghci)
stderr when evaluating that expression.)
doctest you may check whether the implementation satisfies the given examples, by typing:
You may produce Haddock documentation for that module with:
haddock -h Fib.hs -o doc/
Examples from a single Haddock comment are grouped together and share the same scope. E.g. the following works:
-- | -- >>> let x = 23 -- >>> x + 42 -- 65
If an example fails, subsequent examples from the same group are skiped. E.g. for
-- | -- >>> let x = 23 -- >>> let n = x + y -- >>> print n
print n is not tried, because
let n = x + y fails (
y is not in scope!).
You can put setup code in a named chunk with the name
The setup code is run before each example group. If the setup code produces
any errors/failures, all tests from that module are skipped.
Here is an example:
module Foo where -- $setup -- >>> let x = 23 -- | -- >>> foo + x -- 65 foo :: Int foo = 42
Haddock (since version 2.13.0) has markup support for properties. Doctest can verify properties with QuickCheck. A simple property looks like this:
-- | -- prop> \xs -> sort xs == (sort . sort) (xs :: [Int])
The lambda abstraction is optional and can be omitted:
-- | -- prop> sort xs == (sort . sort) (xs :: [Int])
A complete example that uses setup code is below:
module Fib where -- $setup -- >>> import Control.Applicative -- >>> import Test.QuickCheck -- >>> newtype Small = Small Int deriving Show -- >>> instance Arbitrary Small where arbitrary = Small . (`mod` 10) <$> arbitrary -- | Compute Fibonacci numbers -- -- The following property holds: -- -- prop> \(Small n) -> fib n == fib (n + 2) - fib (n + 1) fib :: Int -> Int fib 0 = 0 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2)
Hiding examples from Haddock
You can put examples into named chunks, and not refer to them in the export list. That way they will not be part of the generated Haddock documentation, but Doctest will still find them.
Using GHC extensions
The easiest way to tell Doctest about GHC extensions is to use LANGUAGE pragmas in your source files.
Alternatively you can pass any GHC options to Doctest, e.g.:
doctest -cpp Foo.hs
Doctest provides both, an executable and a library. The library exposes a
doctest of type:
doctest :: [String] -> IO ()
main is simply:
main = getArgs >>= doctest
Consequently, it is possible to create a custom executable for a project, by
passing all command-line arguments that are required for that project to
doctest. A simple example looks like this:
-- file doctests.hs import Test.DocTest main = doctest ["-isrc", "src/Main.hs"]
And a corresponding Cabal test suite section like this:
test-suite doctests type: exitcode-stdio-1.0 ghc-options: -threaded main-is: doctests.hs build-depends: base, doctest >= 0.8
Join in at
#hspec on freenode.
Discuss your ideas first, ideally by opening an issue on GitHub.
Add tests for new features, and make sure that the test suite passes with your changes.
cabal configure --enable-tests && cabal build && cabal test
- Ankit Ahuja
- Edward Kmett
- Hiroki Hattori
- Kazu Yamamoto
- Levent Erkok
- Michael Snoyman
- Sakari Jokinen
- Simon Hengel