こういう実装と、
module FooImpl where
foo :: Foo -> Bar
foo = ...
こういうテストがあったとする。
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。
追記: どのみちリンカーは実行されているので、めちゃめちゃ速くなっているかと言えば微妙な気がしてきた。
まぁ、stackでテストを実行する方法の紹介にもなっているのでいいとするか。
そこで確実にインタープリターで実行できるよう、stack runghc
で個別のテストを実行する方法を調べてみた。
あらかじめ で依存するパッケージをインストールした上で
$ stack test --only-dependencies
# コマンドの内容に反して、実際には依存関係のインストールしか行わない。
# 「依存パッケージのテスト全部実行されちゃったらどうしよう!?」みたいな心配は不要。
のように実行すればよい。
$ 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などのほかのツールを使おう。
なお、 みたいなテストが含まれるひな形はstack-templatesのhspec.hsfilesにあるので、すぐに試したい場合は
$ stack new <作りたいパッケージの名前> hspec
と実行すればよい。
-
単に最適化をオフにしたい場合は
--fast
を渡せばいいらしい。 ↩