JSpec
CouchDBアプリのテストのお話。
- Integration Test は selenium で全部確認。
- Functional Test は CouchDB 自体の test suite と同じように、ブラウザのJavaScriptでXHRを使って view/show/list のテスト。
- Unit Test は ... どうすんの?
という状態でした。
サーバーサイドのJavaScriptテストです。テストフレームワークについては言語毎のまとめがWIkipediaにあるので、そこから選ぶことになりますが、view/show/list を介さずにライブラリだけテストするには
- そもそも添付ファイルとしてデザインドキュメントの_attatchmentsに放り込む
- _attachmentsに入れない場合はXHRでGETしてevalするなどをテストフレームワーク内で仕込む
などなどの工夫が必要で、ぶっちゃけ面倒です。
ということで、Server Side でテストできるものを物色していた今日この頃。JSpec というツールが(私にとっては)最も良さそうです(Test と Specはちげーよ!という声が聞こえてきそうですが)。このツール、当然クライアントサイドもサポートしているので、Unit/Functionalテスト用途に使えそうです。ひとまず今回はUnitテストで。
JSpec インストールする
JSpec はrubyスクリプトなのでrubyとgemはいれておいてください。
$ sudo gem gemcutter $ sudo gem tumble $ sudo gem install commander $ sudo gem install jspec
これでjspecは完了。gem tumble したあとは install jspec にいきなりいってもよさそうだけれど。
サーバーサイドでやるのでRhinoをいれる。
Spidermonekyでやるのが妥当なのでしょうが、仕様上はSpidermonkeyもRhinoも同じハズ、ということで、しばらくは気にしないことにします。なんか問題があったら気にする方向で。
$ export CLASSPATH={RHINO_HOME}/js.jar
Rhino の js.jar は http://www.mozilla-japan.org/rhino/download.html あたりから取得できます。
ライブラリディレクトリを作る。
テンプレートをはき出させます。
$ jspec init mylib
これで mylib/spec とか mylib/lib にファイルが入っています。あとは spec/spec.aaa.js というスペックファイルを書いて、lib/aaa.js を実装するのみ、です。
スペックを書く
数日前に書いた h(string) のスペックを書いてみます。lib/escape.js というファイルにする予定なので、spec/spec.escape.spec という名前にします。
JSpec.describe("escape", function(){ describe("html_escape", function(){ it("should escape '\"'", function(){ var escaped = h('a="a"'); expect(escaped).to(be, 'a="a"'); }); it("should escape \"'\" ", function(){ var escaped = h('a=\'a\''); expect(escaped).to(be, 'a='a''); }); it("should escape '<'", function(){ var escaped = h('a<a<'); expect(escaped).to(be, 'a<a<'); }); it("should escape '>'", function(){ var escaped = h('a>a>'); expect(escaped).to(be, 'a>a>'); }); }); });
RSpec を知っていれば、なんともうれしい書き方!と思うでしょう。ただ、js2-modeのインデントがすごくよろしくないので、http://d.hatena.ne.jp/speg03/20091011/1255244329 を参考にインデントが深くならないように調整すると良いと思います。
spec.rhino.js をいじる
スペックを登録して実行するために、spec/spec.rhino.js に直接書いちゃいます。(とテンプレートがなっていたんですが、コマンドラインで指定したいなぁ)
load('/Library/Ruby/Gems/1.8/gems/jspec-2.11.12/lib/jspec.js'); load('lib/escape.js'); JSpec .exec('spec/spec.escape.js') .run({ formatter: JSpec.formatters.Terminal }) .report();
動かす。
$ jspec run --rhino
結果はこんな感じ(色分けされます)。
yssk22$ jspec run --rhino Passes: 4 Failures: 0 escape html_escape should escape '"'. should escape "'" . should escape '<'. should escape '>'.
これは便利。