読者です 読者をやめる 読者になる 読者になる

middleman 使った場合のユニットテストどうするのがベストプラクティスなの

JavaScript CoffeeScript middleman jasmine karma

情報が少ない。

参考までに私が今やってる環境を書いておく。

  • middleman 使ってCoffeeScriptでガリガリ開発する
  • ユニットテストは jasmine を使って、spec も CoffeScript で書く
  • E2Eテストは今のところまだ考えてない

という状況。jasmine はCoffeeScriptをそのままテストしてくれないので、どうにかして「自動でコンパイルしてテストも走らせる」みたいな環境を整えないとだるすぎてテスト実行しなくなりそうなのでその環境を整えたい。

何に困っているのか

上記の問題は

  • どうやって自動でコンパイルするか = コンパイルツールに何を使うか
  • どうやって自動でテストするか = テストランナーは何を使うか

という問題に分割できる。

テストランナーにはいろいろあって、

  • jasmine に付いてくる SpecRunner.html
  • testem
  • karma

あたりが候補になると思う。testem と karma は CoffeeScript のコンパイルもやってくれるので、普通に考えれば testem か karma を使えばいいよね、という感じになるかと思う。ただ、ここで問題になるのが、「実際のプロダクトコードのコンパイルはmiddleman(というかSprockets)が行う」という部分。

というのも、Sprockets は「JSの読み込み順問題」を解決してくれる require とかの機能持ってるんだけど、karma とかは持ってない。だから何も考えずにやると「Sprockets でコンパイルした場合は正常に動くんだけど、テストランナーで実行した場合は正常に動かない」みたいな感じになる。karma だったら RequireJS 使えば動くようにはなるんだけど、依存性を Sprockets用 と RequireJS 用にふたつ書くのは現実的じゃないし絶対破綻する。

どう解決したのか

というわけで、色々考えた結果、以下のような感じに落ち着いた。

  • PROJECT_ROOT/jasmine 以下に jasmine の lib と spec を置く
  • PROJECT_ROOT/source/javascripts に変化があったら $ bundle exec middleman build で勝手にビルドするようにしておくような Guardfile を書いておいて、$ bundle exec guard -i で監視する。
  • karma.conf.js で files にbuild/javascripts/all.jsjasmine/spec/*を指定しておき、$ karma start --auto-watch で、all.js か spec/* に変化があったら自動でテストを実行するようにする(specがCoffeeScriptで書かれてるので、karma の preprocessor で coffee をコンパイルするようにしておく)。

一応これでうまく動いてはいるんだけど、プロジェクトコードはmiddlemanでビルドしてるのにテストコードはkarmaでビルドするってところと、guardで監視した結果出来上がるファイルをkarmaが監視するという二重監視みたいになってるのが気持悪い。

middleman 環境下で CoffeeScript でテストも書く場合のベストプラクティスはいずこ。