LoginSignup
11
5

More than 5 years have passed since last update.

stack runghcでtestを実行する

Last updated at Posted at 2016-12-29

:point_down: こういう実装と、

src/FooImpl.hs
module FooImpl where

foo :: Foo -> Bar
foo = ...

:point_down: こういうテストがあったとする。

test/FooImplSpec.hs
module FooImplSpec (main, spec) where

import           Test.Hspec

-- 個別のspecファイルを実行するためにはmainが必要。
main :: IO ()
main = hspec spec


spec :: Spec
spec = do
  describe "foo" $ do
    it "returns bar" $ do
      foo bar `shouldBe` foobar

これまでテストを実行するときは stack test などとしていたが、コンパイル遅いし(特にリンカーの実行が遅い)、TDDするには不都合で冗長だった。記憶が正しければ自動で-O1がかかるので、これも素早くテストの実行を繰り返したい場合は邪魔だろう 1

追記: どのみちリンカーは実行されているので、めちゃめちゃ速くなっているかと言えば微妙な気がしてきた。 :sweat:
まぁ、stackでテストを実行する方法の紹介にもなっているのでいいとするか。 :innocent:

そこで確実にインタープリターで実行できるよう、stack runghcで個別のテストを実行する方法を調べてみた。

あらかじめ :point_down: で依存するパッケージをインストールした上で

$ stack test --only-dependencies
# コマンドの内容に反して、実際には依存関係のインストールしか行わない。
# 「依存パッケージのテスト全部実行されちゃったらどうしよう!?」みたいな心配は不要。

:point_down: のように実行すればよい。

$ stack runghc --package <作成中のパッケージ名> test/FooImplSpec.hs

自分自身のパッケージを指定しておくのがポイント。
しなければ「FooImplなんてmoduleないぜ?」と怒られてしまう。

当然、runghcなんで、残りの引数を渡せば実行するexample(it)を絞ることもできる。

$ stack runghc --package <作成中のパッケージ名> -- test/FooImplSpec.hs --match "実行したいexample"
#                                            ^^^^^^
# 「--」を挟まなければ`test/FooImplSpec.hs`ではなく`stack`にオプションが解釈されてしまう恐れがあるので注意。
# この辺の仕様はほかのCLIツールを見習ってもうちょっと柔軟にしてほしい気もする。

なお、hspecに渡せるその他のオプションについてはこちらを参照。

元のstack testで使えた--file-watchオプションと同等なことをしたい場合はwatchexecなどのほかのツールを使おう。

なお、:point_up: みたいなテストが含まれるひな形はstack-templateshspec.hsfilesにあるので、すぐに試したい場合は

$ stack new <作りたいパッケージの名前> hspec

と実行すればよい。


  1. 単に最適化をオフにしたい場合は --fast を渡せばいいらしい。 

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5