Webアプリの大規模化とフロントエンド領域の拡大により、JavaScriptのテストの必要性が高まっている。数ある高機能なテストフレームワークをどう使いこなせば、高速かつ高品質な開発が可能になるのだろうか。
2013年4月27日、六本木ヒルズ森タワーのグーグルにて「第38回HTML5とか勉強会」が開催された。HTML5とか勉強会とは、HTML5に関心のあるエンジニアやWebデザイナ向けの勉強会だ。今回のテーマはJavaScriptのテストフレームワーク。別室のサテライト会場を用意しなくてはならないほど会場は多くの参加者であふれた。テーマへの関心の高さがうかがわれる。テストフレームワークを使いこなす現場のプロたちの解説により、その最新事情と基本的な使い方が分かった。
サイボウズの佐藤鉄平氏は、JavaScriptのテストの基礎知識と全体像について語った。
佐藤氏は、結合テストやユニット(単体)テスト、そのほかにユーザビリティテストなど、そもそもテストにはどんな種類があるのかを解説した後、ユニットテストの重要性を強調した。技術面で開発チームを支援するのがテストであり、大規模な開発において設計とコードの質を向上させるためには必須だと語った。
その方法はテスト駆動開発(TDD)によって行われる。コーディング(あるいは設計)に先立ってテストケースを書き、そのテストをパスするように実装/リファクタリング(きれいなコードに仕上げる)をする。そして、このサイクルを繰り返すことで品質を向上していく。『実践テスト駆動開発』という書籍では、このユニットテストのサイクルに結合テストのループをも含めた「二重のフィードバック」が紹介されている。
なぜ、テストの必要性が高まってきたのか。佐藤氏はその背景を「サーバサイドのロジックがフロントに移動しフロントエンド領域が増大してきた。コードの量も増えてきている。さらにサービスの開発は高速かつ高品質なものが求められる状況である」と説明した。それに伴いテスト環境が向上し、さらにJavaScript向けMV*フレーム【MVC(Model-View-Controller)、MVP(Model-View-Presenter)、 MVVM(Model-View ViewModel)など】やモジュールの仕組みが成熟してきたという。つまり、ユニットテストが行いやすい状況になってきたのだが、どこから手を付けたら良いのか。佐藤氏は、JavaScriptのテストの難しさとして「ビュー(View)とロジック(Model)が結び付いていること」を挙げた。解決策は、「ViewとModelの構造の分離」だ。MV*フレームワークなどの設計を使うことで、純粋なロジックであるModelを分離してテストできる。「まずはModelのテストから始めよう!」とのことだ。
テストツールはいくつかあるが、「どれを選んでも間違いないレベル」であると佐藤氏は話し、会場のコーダーを安心させた。
実行環境の「実ブラウザ(通常のブラウザ)」「ヘッドレスブラウザ(PhantomJS)」「シミュレータ(jsdom、envjs)」のそれぞれの長所と短所を述べた。
実ブラウザでテストをするのが普通と思われるかもしれないが、「ブラウザでテストのHTMLとJSを読み、テストを編集し、さらにブラウザ画面に戻り、更新ボタンを押す」という煩わしさがある。また、実行速度の遅さや複数のブラウザのテストが大変だ。
PhantomJSはWebブラウザなしでJavaScriptの実行が可能なツールだ。そこそこ速度は速く、コマンドラインから扱える。ただしWebkitベースなのでIEでの表示などは当然保証できない。
シミュレータはNode.jsの上でブラウザの動きをシミュレートするが、ブラウザ特有の動きは再現できない。
そういった実ブラウザによるテストの煩わしさを補うツールがある。「リモートテストランナー」だ。「ブラウザをキャプチャリングし、つながれたブラウザに対し、リモートでテストを実行する」というものだ。同時に複数のブラウザでテストができ、さらにテスト内容の変更が即時にすべてのブラウザに反映される。
導入が比較的楽であるとして佐藤氏がお勧めするのが、Jasmine+Testem+実ブラウザの組合わせだ。セッションの後半では簡単なデモが紹介された。
サイバーエージェントの斎藤祐也氏は、BDD(behaviour-driven development、ビヘイビア駆動開発)とは何かを説明し、BDDのテストフレームワークであるJasmineの使い方を紹介した。
斎藤氏は、書籍『テスト駆動JavaScript』でクリスチャン・ヨハンセンが述べている「もしテストするのが難しいのであれば、それはコード自体が悪いのである」という言葉を紹介した後、BDDについて解説した。
BDDはTDDから派生したプログラム開発アプローチであり、TDDの課題や混乱への解決策として誕生した。TDDは6つの疑問(「まずどこから始めれば良いのか」「何をテストすれば良いのか」など)があるが、それらに対するダンノース氏(BDDの創始者)の解答は、「これから作成しようとするプログラムに期待される『振る舞い』や『制約条件』、つまり『要求仕様』に近い形で、自然言語を併記しながらテストコードを記述することが近道である」であった。
つまり、「アプリケーション全体ではなく、小さく、1つのことのみテストする」「テストを文章のように記述する」ことであると斎藤氏はまとめる。また、BDDは開発に対してビジネスの観点を取り込んだアプローチでもあり、テスト結果は技術用語が分からない人も理解できる。テストを書くことが要件仕様のドキュメントにもなりうるという利点もある。
Jasmineは手軽に始められるBDDのテストフレームワークだ。コマンドラインが苦手でも、Node.jsが入っていない環境でも、設定ファイルすら必要なく、ブラウザとHTMLとJavaScriptが動く環境であれば動作する。こちらのサイトから最新版をダウンロードできる。解凍するとダミーのテストコードとアプリケーションコードのサンプルが用意されており、すぐにテストを試すことができる。
斎藤氏は、Jasmineによるテストの基本的な書き方とMatcherの使い方、初期化が必要な場合に使用するbeforeEach()、非同期処理、JasmineのSpy、Jasmineをさらに便利にするツール(Jasmine.async/Jasmine-jQuery/Jamine-sinonなど)を紹介した。テストの書き方やツールの詳しい使い方はセッションの動画が参考になる。
最後に、テストを書く理由として「テストを書くことはデベロッパーズブロックの解消につながる」と述べ、セッションを締めくくった。ライターズブロックというライターが突然文章を書けなくなってしまう状況に開発者もなってしまうことがある。この壁は書くことでしか乗り越えられない。テストを行うことはリファクタリングを容易にし、この壁を乗り越えるためのものである。
ピクセルグリッドの外村氏は、テストダブル(テスト代役)のライブラリであるSinon.JSを紹介した。Sinon.JSは単体で使用するものではなく、QUnitやMocha、Jasmineなどのテストフレームワークを組み合わせて使用するライブラリである。テストダブルとは「テストしづらい部品をダミーに置き換えてテストしやすくする」ものだ。
Sinon.JSの主な機能である「Spy」「Stub」「Mock」「Fake Timer」「Fake XHR」の使い方をコードを示し解説をした。その具体的な解説はセッションの動画が参考になる。
Copyright © ITmedia, Inc. All Rights Reserved.