2013年4月26日、Googleのオフィスをお借りして、第38回HTML5とか勉強会を開催しました。今回のテーマは「Webアプリ×テスト最新事情」。Webアプリとしましたが、今回の内容は主にJavaScriptのテストになります。昨今JavaScriptが利用されるシーンが非常に多くなり、コードの量も多くなってきています。これによりテストが必要になるケースが増えてきていますが、JavaScriptのテストといえばこれ、というものがあまりない現状です。
このような背景もあってか、今回の勉強会の参加率はとても高く、当初予定していた部屋だけでは収まりきらず急遽サテライト会場ができるほどで、JavaScriptテストへの注目度が高いことが伺えました。
本稿では、今回のイベントについてレポートします。
JavaScript Unit Test Why? What? How?
トップバッターとして、サイボウズの佐藤鉄平さんにJavaScriptテストの全体像について紹介いただきました。
昨今のJavaScriptはフロントエンドに求められるものが多くなるにつれて、コードが大きくなり、開発に関わる人も多くなって、コードもチームも大規模になってきています。しかし、同時に速い開発と高い品質の維持も必要です。そこで、JavaScriptにもユニットテストが求められてきています。
この流れとNode.jsの隆盛も相まって、テストを行う上でのツールや、テストがしやすくなるライブラリが多く出てきており、非常にテスト環境がよくなりました。
例えば、JavaScriptでのMV*フレームワークの登場により、モデル(ロジック)とビューを切り分けられるようになり、ロジック部でテストが行えるようになりました。
また、JavaScriptは実際のブラウザ上で実行する必要がありましたが、Node.jsのようにブラウザ以外で実行できる環境が出てきたことや、ブラウザ実行を補助するツールが出てきたため、とても簡単にテストが行えるようになりました。
現在、主に利用されているテストツールの分類は次のようになり、この各分類の中から好きなものを選んで組み合わせてテストするのが良いそうです。
- モックライブラリ
- 外部環境に起因するコードのふりをするオブジェクトを作り、返り値を固定化してテストを行うもの
- テスティングフレームワーク
- テストの書き換えたを決める、優劣はなく自分やチームにあったものを選ぶ
- 実行環境
- 実ブラウザやPhantomjsなどの実際にJavaScriptが動く環境
- リモートテストランナー
- 実際のブラウザからリモートで実行するツール
佐藤さんは、テスト環境が作りやすいためJasmin+testem+実ブラウザの組み合わせがおすすめとのことです。
最後に、「最近のJavaScriptテスト環境はよくできているので、TDD的にやるのも楽しくできるので今すぐやりましょう」と締めくくりました。
詳しくは、講演資料や講演動画をご覧ください。
unit-testing with jasmine
2番目の講演では、サイバーエージェントの斉藤裕也さんにJavaScriptテストティングフレームワークであるJasmineの特徴や使い方について紹介いただきました。
Jasmineは、JavaScriptのためのビヘイビア駆動開発(BDD)のフレームワークです。BDDは、テスト駆動開発(TDD)と同じようにテストコードを最初に書く開発手法ですが、テストではなく仕様(スペック)を実装するのが目的です。テストコードの記述方法は、自然言語に近い形がとられており、これによりテストコード自体の可読性も上がり、これから書くプログラムの仕様理解の手助けにもなります。
Jasmineは、本体をダウンロードしてくるだけでテストができます。設定などを書き換える必要がありません。最新版は、http://pivotal.github.io/jasmine/からダウンロードできます。
ダウンロードしたファイルの中に、すぐに実行できるテストがありますので、どのように使うのかがわかりやすくなっています。
Jasmineにはビルドインで14個のmatcherが用意されていますが、自由に追加することもできるため、自然言語に近い記述でテストを書くことが容易です。使い方は次のようになります。
また、matcherのような基本的な機能以外にも、高度なテストを行うための仕組みも用意されています。それが次の3つです。
- beforeEach/afterEach
- 毎スペックの前後に処理を入れて、データを初期化する等を行う
- waitsFor
- 非同期処理の処理を指定時間待つ
- spy
- 指定した関数に成り代わって、その関数が呼ばれた回数や引数などをしることができる
さらに、Jasmineをより便利にするツールがいくつも存在しています。講演内では次のものを紹介しました。
- Jasmine.async
- Jasmine-jQuery
- Jasmine-sinon
- underscore matchers for jasmine
- javascript testing boilerplate
- javascript-koan
最後に、「テストはデベロッパーズブロックの解消につながる。リファクタリングするにもコードを新規に書くにしても助けるツールになるし、自分のコードの理解もしやすくなるツールにもなる。テストがあることで改変、拡張にも対応しやすくなるので、テストは重要である」と述べ、締めくくりました。
詳しくは、講演資料、講演動画をご覧ください。
Sinon.js
3番目の講演では、ピクセルグリッドの外村和仁さんにSinon.jsについて紹介いただきました。
Sinon.jsは、テストダブルのライブラリです。SInon.js自体がテストフレームワークではないので、テストフレームワークのQUnitやMocha等と組み合わせて使います。
テストダブルとは、テストしづらい部分をダミーに置き換えてテストしやすくするものです。たとえば、AjaxやDateなど外部に影響するようなものを置き換えることで、テストしやすくします。
テストしやすくする機能として、主に次の5つがあります。
- spy
- ダミーに置き換えたオブジェクトが何回呼ばれたか、どんな引数で呼ばれたかを記録する
- stub
- spyを継承した機能で、spyとは違いダミーに変える対象の関数を上書きし、振る舞いまで書き換える
- mock
- stubを継承した機能で、stubとは違い振る舞いをテスト実行前に決めて、テストがその振る舞い通りに動いたかどうかを判定する
- fake timer
- 時間を上書きする。現在の時間だけでなく、setTimeout等の動作確認のために時間を進めて実行確認することができる
- fake xhr
- xhrの動作を書き換える。クライアント側をダミーするだけでなく、サーバ側をダミーにすることもできる
以上のように様々な振る舞いを書き換えテストしやすくすることができます。しかし、外村さんは最後に「Sinon.jsは便利だけど、使いすぎると何をテストしているのかわからなくなる。計画的に使いましょう」とまとめていました。
詳しい使い方については、講演資料、講演動画内で紹介されているため、そちらをご覧ください。
JavaScriptテストフレームワークを眺めてみる
4番目の講演では、TISの佐伯純さんに様々なJavaScriptテストについて紹介をしていただきました。
紹介いただいた内容は、次のテストフレームワークとテストランナーについてです。
- テストフレームワーク
- QUnit
- Jasmine
- Mocha
- テストランナー
- JSTestDriver
- Karma
- Capybara-webkit + Cucumberの組み合わせによる受入テスト
これらの中から選ぶポイントについても紹介しました。
まずテストフレームワークを選ぶ前に、「作るものは?」「何を使って作るか?」「どうやって作るか?」「個人か・チームか」「TDDかBDDか」等のように開発スタイルを決めた上で決めるべきとのことです。それでも迷うようなときは、「自分たちが一番使っていて心地よいものを選べば良い」と締めくくりました。
講演内では、各フレームワークの出自や特徴での比較を行っていますので、ぜひ講演資料、講演動画をご覧ください。
Webアプリ×テスト最新事情 講演者による座談会
最後のセッションは、今回の講演者の方々による座談会を行いました。
テスト未経験者に取り入れてもらうには
佐伯さんは、昔ペアプロで訓練された。会社ではテストをやると最初に決めたらやらなくてはならない。そういう状況で覚えていったとのことです。
斉藤さんは、テストが楽しそうだからでスタートした。だから、テストの楽しさ、例えば赤を緑に変える感じを伝える必要があるとのことです。
佐藤さんは、テストは最初が難しい。だから会社では最初のスケルトンを作成するスクリプトを書いた。これによって今社内で少しずつテストが広まってきているとのことです。
外村さんは、テストをやらざるを得ない状態になる人は少ない。そういう状態にならない人はつまづくことが多いので、簡単なライブラリを作って、そのライブラリでテストをしてみるといいとのことです。
テストを書いていてよかったと思ったエピソード
4人ともリファクタリング関連でテストがあってよかった、テストがないとリファクタリングなんてできないとのことです。
さらに斎藤さんは、プログラムの書き出しの時点からテストがあったほうが、頭の中を整理できるので良いとのことです。
ほかにも、いくつかの議題で座談会が行われました。また、参加者からの質問で「テストの工数を貰う方法」という議題がありました。それらの内容は講演動画をご覧ください。
最後に
レポートに対する感想や、勉強会に対する希望・意見・取り上げて欲しいテーマなどがありましたら、twitter(@yutaro_i)まで気軽につぶやいていただければと思います。
本勉強会は、毎月第3水曜日、または第3木曜日に開催していますので、興味をもたれた方はぜひ参加ください。ただし、会場や講演者スケジュールの都合などにより、開催日程が前後することがあります。
開催のアナウンスはhtml5jのMLで行われますので、こちらをご確認ください。
また、コミュニティサイトも公開していますので、ぜひこちらもご覧ください。