mocha+chai+blanketを使ってcoffeescriptでBDD
最近空いた時間にhubotのadapterを開発してるのですが、coffeescriptでテストを書きたくなったときにちょっと試行錯誤したので備忘録として残しておきます。
目標
- mochaとchaiを使ってcoffeescriptでBDDスタイルのテストを行う
- blanketを使ってcoffeescriptのカバレッジ測定を行う
- (おまけ) travis ciとcoverallsで自動化する
mochaとchaiでBDD
セットアップ
mochaはjs用のテストフレームワークで、C/Sのどちらでも動作します。他のアサーションライブラリと組み合わせて使う必要があるため、今回はBDDアサーションライブラリであるchaiを使います。
まずpackage.json
に以下を追記します。
{ "scripts": { "test": "mocha test" } }
次に必要なmoduleをインストールします。
npm install coffee-script -g npm install chai --save-dev npm install mocha --save-dev
次にtest/mocha.opts
というファイルを作ります。
これはmochaに渡すコマンドライン引数をまとめたものです。
直接引数として渡しても問題ないのですが、長くなりがちなのでこっちの方がのちのち便利かな思います。
--compilers coffee:coffee-script
テストコード
chaiにはTDDスタイルのassertを使う方法と、BDDスタイルのshould/expectを使う方法があります。 個人的にはshouldスタイルが好きなので以下はshoudスタイルの例。
# test/sample.test.coffee should = (require 'chai').should() describe 'String', -> describe '#concat()', -> it 'should return "John Doe"', -> # assert values 'foo'.concat('bar').should.equal 'foobar' describe '#split()', -> it 'should return [1,2,3]', -> # assert arrays and objects 'foo,bar,baz'.split(',').should.deep.equal ['foo', 'bar', 'baz'] describe 'Tweet', -> # async test it 'should post', (done) -> tweet = new Tweet 'Hello!' tweet.post 'Hello!', (err, res) -> done()
その他いろいろな使い方はAPIリファレンスを参照。
sinonと組み合わせて使うのも簡単です。
ちなみに上に書いたコードの中でdescribe
やit
といった枠組みを提供しているのがmochaです。before
やafter
などもあります。
テストの実行
npm test
blanketを使ったカバレッジ測定
もともとcoverallsでカバレッジ測定したかったので、以下の要件でライブラリを探してました。
- node-coveralls対応
- coffeescript対応
- mocha対応
そこで試したのがibrik(coffeescript用istanbul)とblanketだったのですが、ibrikの方はパーサーがエラーで動かず。 結局blanketを使うことにしました。
セットアップ
package.json
に以下を追記します。
{ "config": { "blanket": { "pattern": "src", "loader": "./node-loaders/coffee-script", "data-cover-never": "node_modules" } } }
上記のpatternにカバレッジ計測対象のファイルにマッチするパターンを書きます。
このpatternなんですが、上の例だとフルパスにsrc
が含まれてる場合(/Users/akiomi/src/hoge-project/
など)はプロジェクト直下のファイルがすべて含まれてしまったので"pattern": "hoge-project/src"
とするなどちょっと工夫が必要です。
次はblanketのインストール。
npm install blanket@">=1.1.5" --save-dev
blanketの古いバージョン(1.1.4以前)ではpackage.json
のscriptsの中に設定を書かなければいけなかったのですが、新しいnpmを使っているとpublish時にscriptsに文字列以外が含まれているエラーとなってしまいます。
blanketの1.1.5からはconfigに設定を書くことが推奨となりこの問題が解決されたので、npm publish
を行う場合には1.1.5以上を使用した方がよさそうです。
また原因がわからないのですが、travis-ciでビルドする場合には1.1.5を指定してもうまく動かなかったため、1.1.6が出るまではgitのコミットハッシュを指定するなどして対応が必要です。
そしてmochaからblanketを呼び出すために以下をtest/mocha.opts
に追記。
--require blanket
ここで、カバレッジ測定しやすくするためにMakefile
を作ります。
本当はgruntを使いたかったんですが、travis-ciでgrunt-mocha-covを使って動かすことができず断念…(ローカルの実行ではうまくいくんですが)。
MOCHA = ./node_modules/.bin/mocha .PHONY: test test: $(MOCHA) test test-coverage: $(MOCHA) -R html-cov test > coverage.html
カバレッジ計測
以下のコマンドでテストとカバレッジ測定が出来ます。
make test # テスト make test-coverage # カバレッジ計測
あとpackage.json
の方のscripts.testも変更しておきます。
{ "scripts": { "test": "make test" } }
travis-ciとcoveralls
githubでリポジトリを公開している場合はtravis-ciによるビルドとcoverallsによるカバレッジ計測が簡単にできます。 travis-ciとcoverallsの設定は省略。
まずcoverallsでのカバレッジ計測用のmoduleをインストール。
npm install mocha-lcov-reporter --save-dev npm install coveralls --save-dev
次にMakefile
にtravis-ci用のビルドタスクを追加。
test-coveralls: mocha test --reporter mocha-lcov-reporter | coveralls
あとはプロジェクトルートに.travis.yml
を作るだけ。
language: node_js node_js: - "0.10" script: make test-coveralls
これでリポジトリにpushした段階で勝手にtravis-ciがビルドしてくれて、ビルド結果をcoverallsに連携してくれます。キーやトークンの設定とかも特に必要ありません。
感想とか
今回試したいろいろなライブラリは成熟してないものが多くてハマりポイントが多かったです。 全体的にまだいいやり方があると思うので、もうちょっと試行錯誤してみようと思います。
参考になるかはわかりませんが、以下のリポジトリで実践しています。