Testes de unidade simples usando Cabal em vez de usar diff e make

Dec 16 2020

Gostaria de reescrever meu código de teste de shell para meu aplicativo Haskell para usar apenas Haskell e Cabal. (por razões de portabilidade)

O esquema de teste atual é semelhante a este

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

Eu gostaria de ter algo como

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

Qual é a maneira mais fácil de fazer isso, por favor?

Obrigado.

Respostas

1 leftaroundabout Dec 16 2020 at 03:19

Tasty é uma estrutura simples e versátil para executar vários tipos de testes. (Eu o uso principalmente para testes QuickCheck , que - se você ainda não o fez - recomendo fortemente que você verifique também.)

O tipo específico de teste sobre o qual você está perguntando é chamado (pelo menos no Tasty) de teste de ouro . Então, por exemplo, se o programa que você deseja testar foi

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

então você pode mudar isso para um teste saboroso 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 um .cabalarquivo como

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

Se o programa que você deseja testar tem saída embutida em stdoutcódigo (por exemplo, na forma de printinstruções), você pode precisar modificar um pouco isso.


Não há necessidade real de ter um testGroupaqui, mas na prática você provavelmente desejará ter vários testes nesse arquivo. Tasty permite que você crie uma árvore arbitrária de testes , em qualquer ordem hierárquica que seja útil.