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でやるのが妥当なのでしょうが、仕様上はSpidermonkeyRhinoも同じハズ、ということで、しばらくは気にしないことにします。なんか問題があったら気にする方向で。

$ 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&lt;a&lt;');
    });
    it("should escape '>'", function(){
      var escaped = h('a>a>');
      expect(escaped).to(be, 'a&gt;a&gt;');
    });
  });
});

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
    • rhino 重要です。これで spec/spec.rhino.js を使って、terminalだけで作業できます。ちなみに run を除いて実行すると、terminalに常駐してautospec的なことをしてくれます(変更があったら即テスト)

結果はこんな感じ(色分けされます)。

yssk22$ jspec run --rhino

 Passes: 4 Failures: 0

 escape html_escape
  should escape '"'.
  should escape "'" .
  should escape '<'.
  should escape '>'.

これは便利。

使えるMatcherとかは?

http://visionmedia.github.com/jspec/ にあります。