Testing Haskell

This post explains how to configure your Haskell project for testing, using Cabal and Travis CI.

This post explains how to configure your Haskell project for testing, using Cabal and Travis CI.

I’d like to learn Haskell, but I had a really hard time yesterday to setup the testing environment correctly. So I want to share my experience with you, to make life easier. In this post, we’ll go through the following steps:

  • Adapt project structure to Cabal
  • Configure test
  • Enable Travis CI

Adapt Project Structure to Cabal

Cabal is a system for building and packaging Haskell libraries and programs. Before this blog post, I didn’t know about Cabal and my project have only 2 Haskell files on the top level folder. You can initialize the Cabal structure and generate related files using interactive command line tool cabal init. Once done, editing the <project>.cabal file to add or modify the content.

Then you need to move the Haskell source files *.hs into the src folder.

$ find src -type f
src/factorial.hs
src/Mathematics.hs
src/catalan.hs

If everything works, try configuring and building the package:

$ cabal configure
$ cabal build

Install if it works:

$ cabal install

Configure Tests

For the testing part, I followed Cabal’s documentation: §3.3.2.6 Test suites. It’s very simple, just declare an additional section in your project’s <project>.cabal, as test-suite. (Note: replace test-suite by test won’t work):

test-suite Mathematics
  type:                exitcode-stdio-1.0
  main-is:             test-mathematics.hs
  hs-source-dirs:      src, test
  build-depends:       base
  other-modules:       Mathematics
  default-language:    Haskell2010

In the above section, multiple fields have been declared:

  • The type field indicates the type of test-suite is exitcode-stdio-1.0. It means test suite can indicate test failure with a non-zero exit code when run. It may also provide human-readable log information through the standard output and error channels. The exitcode-stdio-1.0 type requires the main-is field.
  • The main-is field indicates the main program to run.
  • The hs-source-dirs field indicates the haskell source directories are src and test.
  • The build-depends field indicates the dependencies when building this module.
  • The other-modules field indicates a list of modules used by the component but not exposed to users.
  • The default-language field indicates the default language version. It should be aligned with the Library section.

Note: you must run cabal install --enable-tests, then you can run cabal test to run your tests.

Travis CI

Travis CI has a complet documentation page about Building a Haskell Project. In my case, I need to precise the language as Haskell, since Travis CI didn’t detect it correctly (without precision, it used Java and Gradle mistakenly). And I also flatten GHC versions list into oneline. Here’s the result:

language: haskell
ghc: 8.2

References