はじめに
最近趣味でHaskellを書いています。
新しい言語を勉強をする時に、TDDBCで使われるお題(セマンティック・バージョニングなど)を利用することが多いのですが、HaskellでもHspecを使って書いています。
ただ、毎回stack newをしてpackage.yamlなどを書き換えるのも若干面倒だったので、
stack newしたらHspecが設定済みのプロジェクトが作れるように、今回設定をしていきます。
2019/05/06追記
コメント欄でご指摘頂きましたが、
標準のテンプレート集にhspecが用意されているようです。
hspecが設定済みのプロジェクトを使うのであれば、stack new のテンプレート名にhspecを指定して実行すれば使えます。
$ stack new プロジェクト名 hspec
前提
- stackがインストールされていること
- 
$ stack install hspec-discoverで hspec-discover入れていること
手順
stack newのデフォルトテンプレートを開きます。
$ cd ~/.stack/templates/
$ vi new-template.hsfiles
テンプレートファイルを編集します。
tests:
  {{name}}-test:
    main:                Spec.hs
    source-dirs:         test
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - {{name}}
+   - hspec  
{-# START_FILE test/Spec.hs #-}
- main :: IO ()
- main = putStrLn "Test suite not yet implemented"
+ {-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ {-# START_FILE test/LibSpec.hs #-}
+ module LibSpec (spec) where
+ import Test.Hspec
+ import Lib
+ spec :: Spec 
+ spec = do 
+    describe "テストケース" $ do 
+        it "somefuncが返ってくること" $ do
+            someFunc `shouldBe` "someFunc"
{-# START_FILE src/Lib.hs #-}
module Lib
    ( someFunc
    ) where
- someFunc :: String
+ someFunc :: IO ()
- someFunc = "someFunc"
+ someFunc = putStrLn "someFunc" 
{-# START_FILE app/Main.hs #-}
module Main where
import Lib
main :: IO ()
- main = someFunc
+ main = return ()
{-# START_FILE ファイル名 #-}で、プロジェクトを作ったときのデフォルトで作られるファイルと、その中身を設定することができます。
新規作成したらすぐテストが試せるように、デフォルトのファイルの中身を書き換えています。
テンプレートファイルを書き換えたあとは、実際にそのとおりにプロジェクトが出来たか試してみます。
問題がなければ以下のようにデフォルトで作ったテストが通ると思います。
$ stack new example
$ cd example
$ stack test
Progress 1/2: example-0.1.0.0
Lib
  テストケース
    somefuncが返ってくること
Finished in 0.0002 seconds
1 example, 0 failures
これで次回から、すぐテストができるプロジェクトが作成できるようになりました。
上記の説明だと、デフォルトのテンプレートを変更しましたが、
デフォルトを変更するのに抵抗がある人は、~/.stack/templates/に新しいテンプレートを作成しておき、stack newするときに指定をすればテンプレートの使い分けができます。
$ cd ~/.stack/templates/
$ cp new-template.hsfiles my-template.hsfiles
# なにかしらテンプレート編集したあと、任意のフォルダで下記を実行
$ stack new exampleProject my-template.hsfiles
おまけ
stack newで作ったプロジェクトは当然ですがgitリポジトリではありません。
git管理する場合にはプロジェクト作成後に自分でgit initコマンドを叩く必要があります。
作ったプロジェクトを自動的にgitリポジトリにしたい場合は、config.yamlを設定します。
$ vi ~/.stack/config.yaml
templates:
  scm-init: git # 追加
この設定をしておくと、次回からstack newしたときに、git initが自動的にされています。
以上です。