読者です 読者をやめる 読者になる 読者になる

yo_waka's blog

418 I'm a teapot

Google Closure LibraryのユニットテストをPhantomJSで実行するやつ

を2年前くらいに作ったのだけど、久々にGoogle Closure Libraryを使いたくなって、そうなるとテストも書かないとなので引っ張りだして使おうと思ったのですが、なにせ2年前に作ったものなので、ソースコードはレガシー感が漂ってて、使ってるPhantomJSのAPIもdeprecatedになっていたりしたのでいろいろ直してアップデート(リポジトリ名も少し変更)。

waka/closure-library-phantomjs

単一のテストファイルのテストでもマルチテストランナーを使った複数テストファイルのテストでも同じ使い方です。
詳しい使い方やオプションは、READMEに書いた。

最近Mochaでテストを書くことが多いのですが、出力形式をいろいろ選べるの楽しくていいなと思ったので、インターフェース切ってリポーターをいくつか使えるようにした。

実際よく使うのは、見やすいSpec形式と、Jenkins等で扱うためのTAP形式と、テスト数が多い場合のDot形式かなと思ったので、その3つを使えるようにした。
これで、手元での開発に加えて、JenkinsでもTAP-Plugin使ってCIしやすくなった。

昔はQt入れなきゃいけなかったりして、PhantomJSのビルドが結構大変だった記憶があるのだけど、今のPhantomJSはバイナリが提供されていて、すぐに使えて便利。
Node.jsが入ってる環境なら、npmでも入れられる。
Node.jsが使える環境で、コマンドラインからもっと手軽に使いたい場合は、npmにもアップしてあるのでそっちからも使えます。
npm/closure-library-phantomjs
(npmからインストールしない場合はlib以下のJSをどこかに置いてPhantomJSから起動すれば使えます)

PhantomJSの変わった点といえば、CommonJSのmodule1.1をサポートするようになったのは大きい。
これによって起動スクリプト内で他のスクリプトを読み込めるので、起動スクリプトを分割しやすくなった。

あと、1.2から追加されたWebpageモジュールのinjectJSがかなり素晴らしい。
ClosureLibraryのテストランナーはブラウザ実行、つまりDOMに結果を書き出すのが前提で、そのままPhantomJSのconsoleにテストランナーのconsole.log出力を流しても欲しいログが取れない。

なので、テストの実行時間やエラーのスタックトレースを取得するために、goog.testing.TestRunnerやgoog.testing.MultiTestRunnerを拡張したりメソッドを差し替えたり、ということを以前はテストHTML内にスクリプトタグを追加してやっていたのだけど、これだとテストファイル1つ1つに差し込んでいかないといけないので効率が悪いし差し込むの忘れる。

そこでWebpage#onInitializedのハンドラでinjectJSを使うと、ページがロードされてからwindow.onloadが走る直前にスクリプトを差し込めて実行できる。これでテストランナーのscriptタグが読み込まれてオブジェクトを参照可能かつテストランナーが走る前、というタイミングでメソッドを拡張したり差し替えることができます。素晴らしい。

Google Closure LibraryでUI作ってユニットテストも書いて、、って開発しているとこなんてほとんど無いと思うけど、Google Closure Libraryのマルチテストランナーはかなり使い勝手がよいですし、非同期テストもサポートされていてアサーションも完備。

たしかQUnitは複数のHTMLテストファイルを実行できなかったと思うので、複数実行したい場合のテストライブラリとしてGoogle Closure Libraryを使うというのもアリなんじゃないかと思います。
よく飼い慣らされたClosure Library野郎であれば、当然テストのためだけにClosure Libraryを使う。