Integrating your HUnit (or other) tests into your cabal package
As part of one my side projects I'm working on learning haskell, and creating a simple DNSBL lookup tool. An important part of any project, especially one which you plan to build on top off is its testing. There are quite a few options for Haskell testing such as quickcheck,etc., and the one that I ended up using HUnit. Most developers that I know have been burned at one time or another by making some "trivial" change building it and checking it in to only have it fail when running there tests would have caught it.
The solution of course is to integrate your automated tests into the build process. Cabal is a wonderful package build system for haskell. Unfortunately, very few (if any) people seem to use the provided mechanism for hooking in tests. The first set is opening up the Setup.hs (or lhs) file and overriding the default test hooks.
Start off by importing the necessary libraries
Then we need to replace the default main (main = defaultMain) with a main with our command hooks:
Now we need to define runzeTests so that our tests get run. You might be tempted to just through your tests inside runzeTest, but thats a bad idea since your module isn't visible. So we just make the test hook call out to our program:
Now if you've put your sources in a subdir (lets say src) you need to tell runhaskell where to find it, so instead do this
And now its done! You can run your tests with cabal by running
The alternative approach, if you are using darcs, is to set darcs to run your tests:
Or for the best of both worlds, configure cabal as above and set darcs to run your cabal tests:
For those of us who are running in git we can add it to our git pre-commit hooks to keep us from accidentally checking in broken code, just add:
to the bottom of your pre-commit hook file (don't forget to make it executable :)).
We can even make the commit fail if our tests fail by returning the status from the test. Just store the return code where you run the test:
The solution of course is to integrate your automated tests into the build process. Cabal is a wonderful package build system for haskell. Unfortunately, very few (if any) people seem to use the provided mechanism for hooking in tests. The first set is opening up the Setup.hs (or lhs) file and overriding the default test hooks.
Start off by importing the necessary libraries
import Distribution.Simple
import Distribution.PackageDescription(PackageDescription)
import Distribution.Simple.LocalBuildInfo(LocalBuildInfo)
import System.Cmd(system)
import Distribution.Simple.LocalBuildInfo
Then we need to replace the default main (main = defaultMain) with a main with our command hooks:
main = defaultMainWithHooks (simpleUserHooks {runTests = runzeTests})
Now we need to define runzeTests so that our tests get run. You might be tempted to just through your tests inside runzeTest, but thats a bad idea since your module isn't visible. So we just make the test hook call out to our program:
runzeTests:: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO ()
runzeTests a b pd lb = system ( "runhaskell ./tests/mytests.hs") >> return()
Now if you've put your sources in a subdir (lets say src) you need to tell runhaskell where to find it, so instead do this
runzeTests a b pd lb = system ( "runhaskell -i./src ./tests/mytests.hs") >> return()
And now its done! You can run your tests with cabal by running
runhaskell Setup.hs test
The alternative approach, if you are using darcs, is to set darcs to run your tests:
darcs setpref test "runhaskell test/test.hs"
Or for the best of both worlds, configure cabal as above and set darcs to run your cabal tests:
darcs setpref test "runhaskell Setup.hs test"
For those of us who are running in git we can add it to our git pre-commit hooks to keep us from accidentally checking in broken code, just add:
runhaskell Setup.hs test
to the bottom of your pre-commit hook file (don't forget to make it executable :)).
We can even make the commit fail if our tests fail by returning the status from the test. Just store the return code where you run the test:
runhaskell Setup.hs test
code = $?
...[someother precommit hooks]...
exit code
Comments
As as side note, I have implemented a little wrapper that allows you to use QuickCheck Properties from in HUnit.
http://doc.seereason.com/haskell-extra-doc/html/Test-QUnit.html
The source is available via darcs at http://src.seereason.com/haskell-extra
Thats really cool :) More integration between the testing frameworks is winsauce :)
darcs setpref test "runhaskell Setup.hs configure; runhaskell Setup.hs test"