アルバイト先のひとがテスト好きなので、影響されて『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 側に渡らず、エラーの表示が不親切になるのでよくなかった。
