JavaScriptのテストツールを探してみた。
テストを自動化するツールやエラー箇所を特定するツールは見つかったが、 テストの十分性を測定するカバレージツールが見当たらない。
ということで、実行ステップを測定する為のトレースツール(トレーサー)を作ってみることにした。
エラーを検出したJavaScriptファイル名とステップを正確に教えてくれる。
エラーを検出した箇所のソースを表示する。
JavaのJUnitに相当するテスト自動化ツール。 関数を単体でテストする時に使用する。
ブラウザ画面の操作するテストを自動化するツール。 JavaScriptのテスト用というより、WEBアプリケーション全般のテストに使用する。
コマンド等によって予めトレース用のステップを埋め込むのは可能だが、オリジナルファイルと変換後ファイルを 管理しなければならず、スクリプト言語を使うメリットが無くなる。
そこで、CGIやServletを通してJavaScriptファイルを呼び出すようにし、動的にトレース用のステップを埋め込むことにした。
Servletを動作させるのに特別なサーバは必要ない。Tomcat等を使用すればよいので、PC1台でテストが可能である。 PC1台にクライアントとサーバを同居させてテストするのは、いまどきあたりまえか。
トレースを取得する処理方式は、ざっと、次のとおり。
現在プロトシステム作成中。できたところから報告予定。トレースを保存した後が大変そう。
JavaScriptにトレース文を埋め込む。 性能面を考慮し、 ステップ単位に埋め込むのでは無く、ある程度の処理の塊(ブロック)単位に埋め込む。
※if や else の処理ブロックを { } で囲んでいない場合、トレース文を挿入しない為、 トレースの精度が荒くなる。 { } で囲んでいない文が制御文の場合、 変換後のJavaScriptファイルは実行不可能になるか、動作がおかしくなる。
ブラウザからの要求の都度、毎回埋め込み処理をするのは無駄なので、 変換後のソースを保存しておく。
HttpXMLRequestを使用し、非同期にトレースをサーバに送信する。
都度送信するのでは無く、一定間隔(1~5秒)と画面をクローズする時 にサーバに送信する。
※方式変更:旧方式「一定件数たまった時、画面をクローズする時、 デバッグメッセージの送信要求があった時にサーバに送信する」は廃止。 理由:大量にトレースを取得すると、立て続けにサーバにトレースを送信することにより、 サーバに負荷がかかる。これを軽減しようと「一定件数」を増やすと、実行結果を即時に 確認出来ない。
ステップトレース送信機能を利用し、任意の情報をサーバに送信可能とした。
ブラウザから送信されたステップトレースと、デバッグメッセージを保存する。
トレースファイル名は、ブラウザのIPアドレスと年月日を使用している。
ステップトレース文を埋め込んだJavaScriptファイルの一覧を表示する。
ファイルの一覧には、トレース対象行数、実行済み行数、 簡易カバレージ(実行済み行数÷トレース対象行数)を表示する。 ステップ単位でなく、ブロック単位の集計である為、カバレージは正確な値にはならない が、0%と100%だけは正しく計算できる。。
この一覧から「JavaScriptソース・トレース結果」、「変換後JavaScriptソース」 の表示機能へリンクする。
JavaScriptソースに、行番号、トレース取得予定箇所("$")、 トレース取得済み箇所("#")を付与して表示する。
ステップトレースとデバッグメッセージを格納したファイルの一覧を表示する。
この一覧から「ステップトレース・デバッグメッセージ」 の表示機能へリンクする。
ステップトレースとデバッグメッセージを実行順に一覧表示する。
環境作成の前提となるディレクトリ構造の例を次図に示す。
空データを排除する処理を追加(jsdtracesave.java)。
トレースログの即時性の向上と追い越しの防止。トレースの送信タイミングを「一定件数」から「一定間隔」に変更(debug_jsdtracesend.js)。
トレースログを破壊する現象の対策。トレースログ追記に排他制御を追加(jsdtracesave.java)。
トレース送信完了処理のデグレード対策(debug_jsdtracesend.js)。
onunload時にトレースが取られないケースがあるのを対策(common.js)。
Tomcat4でも使えるように、web.xmlのcontext-paramの位置を修正。
ソース表示の文字化け("<",">"が消える)を対策(jsdtracedet.java , jsdtracecash.java)
実験的に作成しているので、プログラムは汚いし、コメントは無いし、という状態である。