Haskell のプロジェクト作成を stack で行いました
Haskell のビルドツールは cabal との2択のようでしたが stack の方が後発とのことで stack を選びました
プロジェクトの作成とユニットテストができるところまでやっています
環境
- macOS 11.6
- zsh 5.8
- stack 2.7.5
stack のインストール
stack はクロスプラットフォームの Haskell のビルドツールです
Haskell のコンパイラである GHC のダウンロードも stack がやってくれます
macOS の場合は brew を使ってbrew install haskell-stack
でインストールできます
(他の OS や方法は公式を参照)
プロジェクトの作成
インストールしたらプロジェクトを作成します
stack new my-project
cd my-project
stack setup # 必要に応じて Haskell のコンパイラである GHC をダウンロードします
ここまででビルド、プログラムの実行ができるようになっています
stack build
stack exec my-project-exe
# stack 2.7.5 では someFunc と表示される
my-project-exe
というのはstack new
で作られるpackage.yaml
で設定されている名前です
executables:
my-project-exe: # ここの名前。このブロックを増やすことで実行コマンドを増やすことができる
main: Main.hs
source-dirs: app
ユニットテストの作成
今回は hspec でテストを作成してみました
hunit というものもあるようですがなんとなく hspec の方が情報量が多い気がしました
まずは依存関係を追加します
# 途中は省略しています
tests:
my-project-test:
dependencies:
- hspec # これを追加
これでテストを書いて実行できるようになります
stack が初期化したテストのソースに追記する場合
import Lib -- src/Lib.hs で hello 関数を export している場合
import Test.Hspec
main :: IO ()
main = hspec $ do
describe "hoge" $ do
it "fuga" $ do
hello "world" `shouldBe` "hello world"
実行はstack test
です
モジュール毎にテストを書く場合
開発を進めていくとモジュール毎にファイル/フォルダを分けていくと思いますが
そのような時はこのように書けます
例としてsrc/Lib.hs
のテストをするtest/LibSpec.hs
を作った場合
import Test.Hspec
import qualified LibSpec
main = hspec spec
spec :: Spec
spec = do
describe "LibSpec" LibSpec.spec -- 作ったモジュールのテストを実行
module LibSpec where
import Test.Hspec
import Lib
spec :: Spec
spec = do
describe "hello world" $ do
it "return hello with name" $ do
hello "world" `shouldBe` "hello world"
test/Spec.hs
が テストスイートになるイメージです
ただし、この場合モジュールが増える度にtest/Spec.hs
を更新する必要があります
hspec はこの部分が楽になるようにAutomatic spec discoveryという仕組みが準備されています
Automatic spec discovery を使う場合
test/Spec.hs
をこのように書いておくと hspec が自動でテストを探して実行してくれるようになります
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
テスト実行の tips
その他、テスト実行について次のことを知っていると便利だと思いました
- 更新を監視して自動でテスト実行したい
- stack の
--file-watch
オプションをつける - 例:
stack test --file-watch
- stack の
- 修正中のモジュールだけをテスト実行したい
- stack の
--test-arguments
オプション経由で hspec の--match
オプションをつける - 例:
stack test --test-arguments "--match SomeLib"
- stack の
感想
プロジェクト作成してとりあえず実行まではそんなに苦労しなかったですが
テスト作ってサードパーティのライブラリインストールしてとかまでやろうとすると
haskell 初心者には難しかったと思います
特に情報を探すのに他の言語と比べて苦労があったと思います
最近の言語であったり利用者が多い言語はそういうところが簡単になってたり
情報がすぐ見つかってありがたいですね
( go や python など)