cabal - installing test dependencies

22 Dec 2013, by Pang Yan Han

If there is one serious pain point I’ve always felt about Haskell, it is the lack of documentation, or if documentation available, it’s usually very terse and feels like it’s meant more for experts than for beginners.

This short article will show you how to install test dependencies for a cabalized project using cabal. The longer version is centred around Yesod, but should be generally applicable. There is a tldr version available below.

Software involved:

  • ghc 7.4.1
  • cabal 1.18.0.2
  • yesod 1.2.4
  • yesod-bin 1.2.5.1

tldr version

In short, suppose you have a cabalized project, and somehow when you run its test suite, cabal complains about missing dependencies. Now, inside the .cabal file of the project, you should find a section beginning with a line that looks something like this:

test-suite test

and below it, there are some build-depends that look like libraries meant for testing. If so, then you are in luck. Simply execute the following commands:

cabal configure --enable-tests
cabal install --only-dependencies --enable-tests

And cabal will go on to install the test dependencies. Once that is done, you should be able to run the test suite.

For a longer version of how I derived the above, read on.

Long version

I was fiddling around with setting up a Yesod scaffolded site, and it went like this:

yesod init
cd yesodtry && cabal sandbox init && cabal install && yesod devel

So my project is named yesodtry. Everything went smoothly, and the Yesod scaffolding comes with a “demo” site, that looks like this:

I noticed the yesod test line, and curiosity got the better of me. So I proceeded to enter yesod test onto the command line, and this was what I got:

Resolving dependencies...
Configuring yesodtry-0.0.0...
cabal: At least the following dependencies are missing:
hspec -any, yesod-test ==1.2.*

Ok, but I noticed that inside yesodtry.cabal, there is a test-suite test section, that looks like this:

test-suite test
    type:              exitcode-stdio-1.0
    main-is:           main.hs
    hs-source-dirs:    tests
    ghc-options:       -Wall

    build-depends: base
                 , yesodtry
                 , yesod-test >= 1.2 && < 1.3
                 , yesod-core
                 , yesod
                 , persistent
                 , persistent-sqlite
                 , resourcet
                 , monad-logger
                 , transformers
                 , hspec

Notice the yesod-test >= 1.2 && < 1.3 line. So somehow cabal is not installing that dependency. Out of desperation, I tried cabal build test, and I got:

cabal: Cannot build the test suite 'test' because test suites are not enabled.
Run configure with the flag --enable-tests

Ok, so it’s telling me to run cabal configure --enable-tests. Below is its output:

Resolving dependencies...
Configuring yesodtry-0.0.0...
cabal: At least the following dependencies are missing:
hspec -any, yesod-test ==1.2.*

which was the exact same output I got from running yesod test !!! So it seems like we’re in a vicious cycle here, with no way out…

So I proceeded to ask a question on stack overflow. After a few minutes, no one responded, and I could not find similar questions. A lucky google search yielded the following link:

https://groups.google.com/forum/#!topic/haskell-cafe/SFoNwaq8wdc

Which is an announcement for the release of cabal 1.18.0, and seemingly has nothing to do with our problem, until the following lines in the announcement:

* GHCi support. It's now much easier to use ghci when developing your
packages, especially if those packages require preprocessors (e.g.
hsc2hs).

Here's how working on a package might look like using the new features:

    # Only once:
    cabal sandbox init
    cabal install --only-dependencies --enable-tests
    # Configure, build, and run tests:
    cabal test  # now implies configure and build
    # Play around with the code in GHCi:
    cabal repl

In particular, the cabal install --only-dependencies --enable-tests line. Could that be the magic one liner needed to solve our problems? Fortunately, yes.

So I proceeded with:

cabal install --only-dependencies --enable-tests

and cabal goes on to install the dependencies for the test-suite test section.

Then, I proceeded to run:

yesod test

And here’s the last few lines of output:

Linking dist/build/test/test ...
Building yesodtry-0.0.0...
Preprocessing library yesodtry-0.0.0...
In-place registering yesodtry-0.0.0...
Preprocessing test suite 'test' for yesodtry-0.0.0...
Linking dist/build/test/test ...
Running 1 test suites...
Test suite test: RUNNING...
Test suite test: PASS
Test suite logged to: dist/test/yesodtry-0.0.0-test.log
1 of 1 test suites (1 of 1 test cases) passed.

And I felt a sense of accomplishment… even though I wasn’t really interested in learning how to test a yesod web app at this point in time.

comments powered by Disqus