Přemysl Šťastný
Přemysl Šťastný

Reputation: 1832

Simple unit tests using Cabal instead of using diff and make

I would like to rewrite my shell testing code for my Haskell application to use only Haskell and Cabal. (for portability reasons)

Current testing schema looks like this

make      ->    binary                                     ->  ok or fail
make test ->    diff $(binary test-in) test-supposed-out   ->

I would like to have something like

cabal build  ->  binary                                             ->  ok or fail
cabal test   ->  ...testing with test-in and test-supposed-out...   ->

What is the easiest way to do this please?

Thanks.

Upvotes: 1

Views: 465

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120711

Tasty is a simple and versatile framework in which to run various kinds of tests. (I mostly use it for QuickCheck tests, which – if you haven't yet – I highly recommend to check out as well.)

The particular kind of testing you're asking about is called (at least in Tasty) a golden test. So, for instance if the program you want to test was

module ComplicatedProc where

import System.IO
import System.Environment (getArgs)

complicatedProc :: String -> Handle -> IO ()
complicatedProc input outHandle = do
   hPutStr outHandle $ drop 37 input ++ take 46 input

main :: IO ()
main = do
  [inpFp] <- getArgs
  input <- readFile inpFp
  complicatedProc input stdout

then you could change this into a Tasty test test/golden.hs:

import Test.Tasty
import Test.Tasty.Golden

import ComplicatedProc (complicatedProc)

import System.IO

main :: IO ()
main = do
 complicAlgo_input <- readFile "test-in"
 let complicAlgo_outFp = "test-supposed-out"
 defaultMain $ testGroup "Tests" -- †
   [ goldenVsFile "complicatedAlgo (golden)"
      "test-supposed-out" complicAlgo_outFp
      ( withFile complicAlgo_outFp WriteMode
            $ complicatedProc complicAlgo_input )
   ]

Use a .cabal file like

cabal-version:       >=1.10

name:                compli-algo
version:             5.7.6.8
build-type:          Simple
-- ...

library
  exposed-modules:     ComplicatedProc
  build-depends:       base
  default-language:    Haskell2010

test-suite compli-algo-goldentest
  main-is:         golden.hs
  type:            exitcode-stdio-1.0
  build-depends:       base
                       , compli-algo
                       , tasty >=1.4 && <1.5
                       , tasty-golden >=2.3 && <2.4
  hs-source-dirs:   test

If the program you want to test has outputting to stdout hard-coded (e.g. in form of print statements) then you may need to hack around this a bit.


There's no real need to have a testGroup at all here, but in practice you'll probably want to have multiple tests in that file. Tasty allows you to create an arbitrary tree of tests, in whatever hierarchical order is useful.

Upvotes: 1

Related Questions