連載
» 2012年10月10日 18時00分 公開

PhantomJSとJasmineで振る舞い駆動開発なJavaScriptテストフレームワークで実践! JavaScriptテスト入門(2)(3/3 ページ)

[竹澤陽,TIS コーポレート本部 戦略技術センター]
前のページへ 1|2|3       

PhantomJSを使ってJasmineのテストを実行する

PhantomJS付属のサンプルを使ってJasmineのテストを実行する

 PhantomJSには、さまざまなサンプルスクリプトが付随していますが、その中に「run-jasmine」というスクリプトが存在します。これはその名の通り、指定されたURLにアクセスしてJasmineのテストを実行し、その結果をconsoleに書き出すスクリプトです。

 まずは、このスクリプトを試してみたいところですが、PhantomJS 1.7.0付属のrun-jasmine.jsはJasmine 1.2.0用、run-jasmine.coffeeはJasmine 1.1.0用の記述がされており、今回インストールしたJasmine 1.2.0の結果を取得するためには、run-jasmine.jsの方を使用する必要があります。

$ phantomjs ~/phantomjs/examples/run-jasmine.js http://localhost:8080/SpecRunner.html
run-jasmine.jsの実行結果

run-jasmineをカスタマイズする

 付属のrun-jasmineは公式ページで「However, these are for illustration purposes, it lacks important reporting features necessary for real-world uses.」(これらのスクリプトは説明用で、実際に使うためには必要な情報が欠けているよ)とあるように、Jasmineの実行結果から特定の部分を抜き出した形になっています。

 テストフレームワークの常としてJasmineもテスト結果をどう扱うかはReporter(log4XXX系のAppender相当)に委譲されており、オリジナルのReporterを作って「jasmine.getEnv().addReporter(repoter)」を呼び出すことで、テスト結果の取り扱いを変更できるようになっています。

 Reporterの差し替えとなると変更点が大きくなってしまうため、今回の記事ではReporterの差し替えまでは行わず、既存のrun-jasmineスクリプトの修正で以下の2点を改善してみたいと思います。

  • テストの実行数が分からない、テストの切れ目が分かりづらいといった表示に関する問題
  • expectで失敗した場合、どこで失敗したかのスタックトレースが表示されない問題

テスト結果の見た目を変更

 run-jasmine.jsの中身を見てみると、waitFor関数の第1引数に渡している無名関数(56〜59行目)がJasmineテストの終了チェック、第2引数に渡している無名関数(61行目以降)がJasmineの結果を収集している部分になっています。2点の問題のうち、前者に関しては見た目の問題なので、61行目以降を修正すれば出力を変更できそうです。

 今回はRSpecの出力結果に似せて出力を変更してみました。

run-jasmine-incompete.jsの実行結果

expectで失敗した場合のスタックトレース表示

 見た目は比較的簡単に修正できますが、厄介なのがこちらの問題です。実際のWebブラウザから確認すると、「div.stackTrace」にスタックトレースが格納されているため、単にこれを「console.log」で出力すれば良いように見えますが、先ほどの画像を見ると分かるように、実際にはこれでは一部しかうまくいきません。

 例外をthrowしている場合には正常にスタックトレースが表示されていますが、expectに失敗した場合は実際のWebブラウザでは表示されていたスタックトレースが表示されなくなってしまっています。

 連載第1回の記事にもありましたが、WebKitエンジンとはいえ、実際のWebブラウザとは異なるところがあり、この問題はその一例といえます。

 通常のWebブラウザ、例えばGoogle Chromeで「console.log(new Error().stack)」を実行するとスタックトレースが表示されます。

Error: sample
    at child (http://example.co.jp/index.html:14:21)
    at parent (http://example.co.jp/index.html:17:9)
    at HTMLInputElement.onclick (http://example.co.jp/index.html:23:145)

 しかしphantomjs上で同じコードを実行してもundefinedとなってしまいます。Jasmineではexpectに失敗した場合に、同様のコードを実行しているため、実際のブラウザではスタックトレースが取得できるが、PhantomJSでは取得できないという問題が発生してしまいます。

 Jasmine側を変更する方法もありますが、今回は「スタックトレースが取れないのはexpectの場合だけで、例外が発生した場合にはPhantomJSでも正常にスタックトレースが取得できる」という点に注目して、run-jasmineの変更を行いました。

 変更後のrun-jasmineではexpectに失敗した際に使用されるクラス「jasmine.ExpectationResult」のコンストラクタをフックし、例外の発生とスタックトレースの取得を行うようになっています。

 これに無駄なスタックトレース表示を抑制するなど、いくつかの変更を加えた結果、出力結果は以下のようになりました。RSpecライクでなかなか見やすい形になったのではないでしょうか。

run-example.jsの実行結果

Railsと相性の良いJasmineの拡張も使ってみよう

 連載「フレームワークで実践! JavaScriptテスト入門」第2回では、PhantomJSとJasmineを使ったテスト環境を構築するまでをまとめましたが、いかがでしたでしょうか。

 今回の記事ではテストの自動実行にまで踏み込んではいませんが、JasmineはRailsプロジェクトと相性が良く、Gem版の「jasmine-gem」、RailsのAsset Pipelineを統合してCoffeeScriptを扱えるようにする「Jasminerice」、ファイルの変更を監視して自動的にJavaScriptテストを実行する「Guard-Jasmine」などが作られています。

 またGuard-Jasmineには、JasmineのReporterを差し替えるスクリプトが含まれているため、独自のReporterを作る場合にも参考になるかと思います。

 PhantomJSは内部にWebKitブラウザを含んだJavaScript実行環境のため、JavaScript製のテストフレームワークであれば、Jasmineに限らずさまざまなテストフレームワークを動かせます。

 次回はPhantomJSはそのままに、Jasmineを「QUnit」に変えた場合の例を見ていきたいと思います。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。