トップ «前の日記(2013-06-26) 最新 次の日記(2013-07-05)» 編集

Route 477



2013-06-27

[rails][javascript] JavaScriptのテストフレームワークをRailsのためにパッケージングしたKonachaを使ってみた

「RailsでJavaSciriptのテストを」と言った場合、画面上でダイアログ開く処理とかをcapybara-webkitやpoltergeistでテストしたい…という話のときと、 そうではなくシングルページアプリとかでJS部分に複雑なロジックがあり、その部分をテスト駆動的に開発したい…というケースの2種類がありますが、今日は後者の話。

Rails + CoffeeScriptでぷよぷよシミュレータを書いていたのだけど、coffee部分のテストがしたくなって「coffeescript テスト」でググったところ、Konachaというライブラリが見つかった。

試してみたところ、何も考えずに手順に従ってセットアップするとすぐにテストが書き始められる感じで大変素晴らしかった。 KonachaはRailsエンジンとして実装されていて、spec/javascripts以下にテストを置いて、「bundle exec rake konacha:serve」からの「open http://localhost:3500」で、JSのテストをブラウザ上で実行できる。 コマンドラインからの実行もサポートしているらしい。

書き方

具体的なテストフレームワークとしてはMochaが使われている。 Mochaはmatcherが外出しになっているので別途ライブラリが必要だが、KonachaではChaiを使うことになっている。 多様性は善とはいえ、こうやって作者おすすめのものがパッケージ化されていると、ものぐさな僕なんかには有難い。

MochaはRSpecに近い語彙を採用していて、describe, context, it, before, beforeEachなどが使える。例えばこんな感じ(CoffeeScriptの場合)。

describe "Puyo", ->
  it "has color", ->
    expect((new Puyo).color).to.a("string")

expectやtoはmatcherなので、MochaではなくChaiの担当部分になる。Chaiは「x.should.equal(1)」「expect(x).to.equal(1)」「assert.equal(1, x)」の3つの書き方をサポートしていて、好きなものを使うことができる。とはいえ、Mochaと組み合わせる場合はここだけassertというのも変だし、RSpecはexpectを推しているので特にこだわりがなければexpectを使うのが良いかと思う。*1 *2

ちなみにMocha/Chaiにはmock/stubの機能がないので、必要ならsinon.js等を組み合わせることになる。Konacha本体にはsinon.jsは含まれていないが、konacha-chai-matchersというgemを入れると 「#= require sinon」でsinon.jsがロードできるらしい。

Tipsとか

困ったのが、エラーが発生したときにそれがMochaにキャッチされてしまうため、いつもみたいにconsoleからスタックトレースが見れないこと。 これは、以下のようにいったんキャッチしてからconsoleにe.stackを表示させることで解決した。

it "...." ->
  try
    doit()
  catch e
    console.warn e, e.stack
    throw e

あと、READMEを見てコード中に「debugger」と書いておくとChromeのデバッガを起動できることを知った。

*1 あとfoo.bar.should.equal(1)って可読性が低いので、expect(foo.bar).should.equal(1)の方がまだ良い

*2 余談だけどexpect('foo').to.have.length.of.at.least(2);とかになるともうどれが意味のある関数なのか全く分からないし、API設計として間違ったゴール(英語としての可読性)を目指してる感ある