KarmaでTDD + Travis CI + Coverallsなイケてるワークフロー
巷でAngularJSが盛り上がっているのを横目に、最近は黙々とKarmaを触っていました。Karmaはかなりよくできていて素晴らしいと思うんですが、具体的な使い方はあまり見ないので紹介したいと思います。
Karmaについて
http://karma-runner.github.io/
Karmaはいわゆるリモートテストランナーです。リモートテストランナーというと、色んなブラウザでテストを走らせることが目的のように思えますが、そうではありません。Karmaは ワークフローの問題を解決すること に主眼が置かれています。なので、コマンドラインでテストを実行するほかに
- ファイルの変更監視
- CIサーバとの連携
- デバッグのサポート
- プラグインによる機能拡張
といった機能を持っています。実際に使ってみると、単にテストを実行してくれるだけでなく、ワークフローが劇的に変わることを実感できると思います。
Karmaの特徴
個人的にいいなと思うKarmaの特徴について。
ドキュメントが豊富
公式ページのドキュメントが充実しています。とりあえずドキュメントをざっと眺めれば使い始めることができますし、CIサーバとの連携方法など使い始めたら気になる所も網羅されていて好感が持てます。
あとリポジトリのルートに置いてあるthesis.pdfにはKarmaの設計思想やアーキテクチャがコンパクトにまとまっていて、全体を把握するのに役立ちました。
プラグインで拡張できる
Karmaはテストフレームワークのサポートやレポーター・プリプロセッサなど機能の多くがプラグインになっています。代表的なものは公式プラグインとして提供されていて、ほかにもユーザーが作成したプラグインが数多く公開されています。おかげで、テストに関する様々な要求に柔軟に対応できます。
たとえば、
- テストフレームワークはMochaとchaiとsinonで
- プリプロセッサでCoffeeコンパイルして
- 開発中のレポーターはspec形式 + Growl通知で
- ビルド時はJUnit形式のレポートとカバレッジレポートがほしい
なんていう場合にもプラグインの設定をちょいちょい変えるだけでOKです。
実績がある
実際に現場に投入するとなると、ちゃんと動くかどうかが気がかりです。とくに大規模なプロジェクトはJSファイルが数千になったりするので、安易に乗り換えた結果まともに動かないという事態は絶対に避けないといけません。
Karmaはその点GoogleやYoutubeで実際に使われているという実績があり、その安心感はデカイです。
Karmaのサンプルプロジェクト
そんなKarmaを使うと、「TDDしてCIしてカバレッジを見て...」というワークフローがかなりイケてる感じになります。試しにそのワークフローが体感できるリポジトリを作ってみました。
ama-ch/karma-intro
https://github.com/ama-ch/karma-intro
Karmaのセットアップ方法や基本的な使い方は割愛します。公式ドキュメントや入門エントリを参照してください。
概要
- テストフレームワークはMocha + expect.js
- 開発(TDD)中はChrome & Firefox & PhantomJSでテスト実行してGrowl通知
- ビルド時はPhantomJSでテスト実行してカバレッジレポート作成
- Travis CIでビルド
- Coverallsでカバレッジ確認
基本コマンド
grunt karma:dev
でTDD用の設定でKarmaが起動します。起動した状態でコードを変更すると自動でテストが走って、Growlでポコポコ通知してくれます。Ctrl+Cで終了します。
grunt karma:ci
でCI用の設定でKarmaが起動します。PhantomJSだけでテストが実行されて、実行後は即終了します。
grunt coverage
でCoverall用のカバレッジレポートを作成して、Coverallにポストします。手元で直接叩くことはないです。
CI設定
.travis.ymlはこんなかんじ。
language: node_js node_js: - 0.10 before_script: - npm install -g grunt-cli script: - grunt karma:ci after_success: - grunt coverage
grunt karma:ci
してgrunt coverage
するだけです。簡単ですね。
機能追加ワークフロー
では、このリポジトリで何か機能を追加するワークフローを考えてみます。
1.フィーチャーブランチを切る
まず実装用のブランチを切ります。
2. grunt karma:dev
でTDDを開始する
Karmaが起動してコードの変更を監視します。
3. 実装する
コードを変更すると自動でテストが走って結果がGrowlで通知されます。
4. デバッグする
テストが意図せず失敗したときは、デバッグをします。
コンソールを開くとスタックトレースが表示されているので、参考にしましょう。
コンソールを見てもよく分からない場合は、Karmaのデバッグ画面(http://localhost:9876/debug.html)を開いてdevtoolsでデバッグします。
5. pushしてプルリクエストを作る
実装が一段落したら、ブランチをプッシュしてプルリクエストを作成します。
6. プルリクエストでビルド結果とカバレッジを確認する
pushと同時にTravis CIのビルドとCoverallsのカバレッジレポートが実行されます。これは快適ですね!
とまあこんな具合でTDDしつつCIしてカバレッジできてイケてるよねーとかそんな感じですが、これはNode.jsの開発を超速化するGitHub連携 三種の神器 - teppeis blogの パクリです。 「それKarma使えばWebアプリでもできるよ!」って言いたかっただけです。
使ってるプラグインなど
grunt-karma
公式のGruntプラグインです。タスクごとにKarmaの設定を書き換えることができるので、これでCI用の設定などを書き分けています。
karma-spec-reporter
テスト結果をMochaのspecレポーター風に出力してくれるプラグインです。デフォルトのレポーターは通ったテストをほとんど表示してくれないんですよね。バババッと一覧で見たい人にはありがたいプラグインです。
grunt-karma-coveralls
これはKarmaのプラグインじゃなくてGruntプラグインです。Karmaで作成したカバレッジレポートをCoverallsにポストしてくれます。事前にカバレッジの計測をしておく必要がありますが、Karmaならkarma-coverageで一瞬でできちゃいます。
TestemかKarmaか
ちょっと違う話題になりますが、せっかくなので。
提供する機能が大体同じなのでどっちでもいいと思いますが、大規模プロジェクト*1ではKarmaをオススメします。
Karmaを触る前はTestemを調べていたんですが、大量のJSを読み込むとファイルディスクリプタの上限に引っかかって動かなかったりwatchでCPUリソースを食い潰して死亡するという現象が発生したため断念しました。
とはいえTestemはレポーターがかっちょいいですし、基本はやっぱり好みで決めて、問題が起きたら他のも検討してみるくらいでちょうど良いんじゃないかと思います。
まとめ
Karmaを使うとテストが自動で動かせるだけじゃなくて、CI連携やカバレッジ計測もできるようになります。まさにワークフローが変わります。AngularJSも良いけどKarmaもぜひ使ってみてください!
*1:読み込むJSのファイル数が数百を超えてくるイメージです。