diffとmakeの代わりにCabalを使用した簡単な単体テスト

Dec 16 2020

Haskellアプリケーションのシェルテストコードを書き直して、HaskellとCabalのみを使用したいと思います。(移植性の理由から)

現在のテストスキーマは次のようになります

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

のようなものが欲しいのですが

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

これを行う最も簡単な方法は何ですか?

ありがとう。

回答

1 leftaroundabout Dec 16 2020 at 03:19

Tastyは、さまざまな種類のテストを実行するためのシンプルで用途の広いフレームワークです。(私は主に QuickCheckテストに使用します。まだ行っていない場合は、チェックアウトすることを強くお勧めします。)

あなたが求めている特定の種類のテストは、(少なくともTastyでは)ゴールデンテストと呼ばれます。したがって、たとえば、テストしたいプログラムが

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

次に、これをおいしいテストに変更できます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 )
   ]

次の.cabalようなファイルを使用します

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

テストしたいプログラムがstdoutハードコードされた(例えばprintステートメントの形で)出力を持っているなら、あなたはこれを少しハックする必要があるかもしれません。


ここに実際に必要なものはまったくありませんtestGroupが、実際には、そのファイルに複数のテストを含めることをお勧めします。Tastyを使用すると、有用な階層順序で、任意のテストツリーを作成できます。