MozRepl でテストつき Firefox プログラミング

September 4th, 2007

アルバイト先のひとがテスト好きなので、影響されて『Working Effectively With Legacy Code』を読んでいる。英語は得意ではないので、ちゃんと読めているかというとあやしいのだけど。

Firefox の拡張も単体テストを書きつつ作っていくのが良いかと思って、mozrepl-test というのを書いてみた。

つかいかた

config.rb を環境にあわせて適切に編集した後 make して、できた mozrepl-test を PATH の通ったフォルダに置いてください。

こんなテストコードを

JSAN.use('Test.Simple');

plan({ tests: 4 });
ok(1 == 1);
ok(2 != 2);
ok(3 == 3);

a.js として保存して MozRepl を起動した状態で

% mozrepl-test a.js
1..4
ok 1
not ok 2
#     Failed test
ok 3
# Looks like you planned 4 tests but only ran 3.

こう実行できます。mozrepl-test は引数に渡されたファイルを順に eval するので、

% mozrepl-test lib.js test-lib.js

といった感じで自分は使っています。

今後の課題

ブラウザのグローバルな環境を汚染しまくりなので、なんとかしたい。

9/5 追記

なんとかした

実装

そもそも MozRepl が含まれている Mozlab には MozUnit というテストフレームワークがあるし、MDC にもそれとは別に Writing xpcshell-based unit tests という文章がある。じゃあなんで自分で作るかというと、

  • テストフレームワークそのものはクロスブラウザ開発でも使える
  • シェルから実行できて、実行結果を標準出力に吐く
  • そこそこ手軽に使いはじめられる

なものが欲しかったからで、前述の二つはこの条件を満たせなかった。もちろん、自作してみたかったというのも少なからずあるけど。

実行環境は Firefox + MozRepl で、Ruby から telnet でつないで JavaScript を流し込んでいる。Firefox の ChromeWindow 上で実行されるので、各種 XPCOM がまじったコードも通る。

テストフレームワークには、JSAN (プロジェクトのほう) にある Test.Simple, Test.More を使った。この二つが共用している Test.Builder はブラウザだけじゃなく Director MX 2004 でも動くようにできていて、このとき出力には trace 関数を使用している。

JSAN (ライブラリのほう) は本物ではなく MochiKit の SVN にある FakeJSAN.js を使った。FakeJSAN.js は SpiderMonkey にある load 関数でローカルのファイルを読み込もうとする。

というわけで、repl.print を呼び出す trace と、repl.load を呼び出す load をそれぞれ定義して、FakeJSAN.js, Test.Builder と MozRepl をつないでいる。 あと Test.Builder は実行が終了すると環境も終了することを前提としていて、複数回実行できないので、そこらへんをごまかすコードが少し。

load 関数は、try-catch で例外をつかまえて、業界標準の「ファイル名:行番号: メッセージ」書式で表示するようにしたので、Emacs でエラーから行番号に飛べてうれしい。mozrepl-test の引数にわたすファイルも同様に load で読み込んでいる。初期の実装ではRuby でファイルを読んで、Firefox 側には eval だけをやらせていたんだけど、これだとファイル名の情報などが Firefox 側に渡らず、エラーの表示が不親切になるのでよくなかった。

参考