2014年4月28日月曜日

【追加】最強モックツール JMockit その12 カバレッジオプション

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

只今、私の現場ではこのブログを参考資料としてJUnit開発を進行中!!

そこで現場の皆様からリクエストが上がりましたので、ちょっと昔に巻き戻って情報を補強させて頂きます。

カバレッジオプション

JMockitにはカバレッジ出力機能が備わっている事は第2回でご紹介致しました。

JMockitのカバレッジ出力は簡単でして、jarファイルをインポートすれば勝手に出て来ます。
なので前回の記事では簡単に済ませてしまいましたが、ちょっとカスタマイズしたいという事情が出て来ましたので、オプションにてご説明しましょう。

カバレッジについて記述されている公式ページは以下になります。

機能のご紹介としては、概ね以下のような内容です。

coverage-output

カバレッジの出力モードのオプションです。
普通に実行するとHTMLファイルのカバレッジ結果が出力されますが、モードを設定することによって「シリアル」「マージ」といった機能が解禁されます。

「シリアル」「マージ」というのは、JUnitテストの分割で使用するパラメータです。

普通、JUnitのカバレッジというのは1回で全部出力しなければなりませんが、「シリアル」で実行するとcoverage.serという途中ファイルが出力されます。
これがシリアルファイルです。

複数に出力したシリアルファイルを合体させてHTML出力する機能を「マージ」と言います。

基本、JUnitは1クリックで全部出力するのが良いですが、「シングルトン」とか使ったプログラムですと、どうしても1回ではカバーしきれない場合があります。
そういう時に「シリアル」「マージ」のオプションを使うのが良いでしょう。

coverage-outputDir

カバレッジ出力先を指定するオプションです。
普通に実行すると実行パス直下に「coverage-report」というフォルダが出力されますが、違う場所に出力したい場合に使用します。

coverage-srcDirs

カバレッジ出力対象とすろソースフォルダのパスを指定するオプションです。
デフォルトでは「src」の配下を対象とするので、プロジェクト作成時に「srcフォルダ」「testフォルダ」の2つに分割するのが基本構成であるのは、第2回でご紹介したとおり。

しかし何らかの事情でsrcフォルダ配下にソース、という構成が取れない場合は、このオプションを使用して対処します。

coverage-classes

カバレッジ対象とするJavaファイルを正規表現で絞り込む機能です。
通常ですと全Javaファイルを走査してカバレッジを出力しますが、このオプションによって「特定パッケージだけ」等の対応が可能になります。

coverage-excludes

こちらはcoverage-classesの反対で、正規表現で特定Javaソースを除外する機能です。

coverage-metrics

カバレッジの網羅パターンを指定します。
デフォルトで実行すると「C0(行網羅)」でカバレッジが出力されますが、
オプションを指定することで「C1(分岐網羅)」「C2(条件網羅)」のモードに切り替えることが出来ます。

coverage-check

カバレッジ率をチェックするオプションです。

普通に実行すると単にカバレッジが出力されるだけですが、オプションを指定することにより「指定数値よりカバレッジが低い場合」に警告を出してくれるようになります。

オプション実行

如何でしたでしょう?
最強モックツールに相応しい、痒いところにまで手が届く充実したオプションシリーズですね。

しかし、基本的には「オプションを使わなくても良いようにプロジェクトを運用する」のが大事になるかと思います。
オプションを使用するということは、それだけ複雑になるということですから。。。

しかし、どうしてもオプションを指定して実行しなければならなくなることもありますので、Eclipseでオプション指定実行をする手順もこの記事にて掲載します。

実行の構成から指定する


EclipseからVM起動オプションを設定する場合、基本は以下のように実行の構成から指定することになるでしょう。


  • 右クリック⇒実行の構成⇒引数

ここから、「-Dcoverage-metrics=all」のように、頭に「-D」をつけた引数を入力すれば、それでオプション付きで実行したことになります。


しかしですね、これをやると「ファイル毎に起動構成を作らなければならない」という欠点があります。

JUnitテストなんて、色々なテストケースを何度も何度も実行するものですから、毎回毎回オプションを気にしながら実行するのは面倒極まりないと思います。

そこで、私としては「デフォルトVM引数」を指定するのをオススメします。

デフォルトVM引数指定

Eclipseには「いつも同じVM引数をつけて実行する」というデフォルト指定モードがあります。
VM引数指定が必要な実行があるなら、こちらにすることで手間を省くことをオススメしたいです。

  • ウィンドウ⇒設定⇒Java⇒インストール済みのJRE

VM引数はVM単位で付与しますので、実行時に使用するJavaVMを選び、編集をクリックして下さい。
すると、「デフォルトのVM引数」という項目があるので、ここに入れて実行すればOKです。



こうすることで、最初にデフォルト指定しておけば、いつも同じ設定で実行出来るようになりますので、テストコード開発も捗るでしょう。

終わりに

久しぶりのJUnit記事になりました。

現在、私は現場でこの記事をベースにJMockitを使ったユニットテスト開発を行っていますが、やっぱりJMockitは強力ですね。
出来ないことが無いというくらいに、何でもJMockitで貫き通せています。

次回も現場で出て来た要望への対応、「プライベート変数書き換え」をお送りします。

現場で使っているライブラリ「Spring」のDI機能をモック化する為の特殊対応です。

2014年4月8日火曜日

【GAE】スピンアップ問題4~Ajax作戦~

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

只今、クラウド基盤「Google App Engine(以下、GAE)」の連載しています。

現在はGAE界最大の敵である「スピンアップ」のシリーズです。

本日はスピンアップ編の最終章、Ajax作戦についてです。

重いものは重い

さて、前回のおさらいからですが、GAEのスピンアップは重いものです。
限界までチューニングした所で数秒、現実的には7~8秒は必要とすると見込んで良いでしょう。

つまり、


  • 最初に表示した時、画面が10秒近くホワイトアウトしている。


こういう現象に陥ってしまうわけです。
今回はこの現象に対する対抗策に関する内容です。

我慢作戦

まあ、「スピンアップ」というのはインスタンスが起動する時だけ重いものですから、
最初の一回だけ我慢すれば、後は速いものですよ。

私は過去に負荷テストを行っていますが、
その時の実績によると、20~25人がF5アタックしているような状態でも1インスタンスで捌けてしまいます。

つまり、普通の人が普通にアクセスするペースだと、その10~20倍の250~500人程度は、スピンアップが最初の1回以外は発生しない見込みになります。

何が言いたいかと言いますと、

  • ホワイトアウトなんて滅多に起きないんだから我慢しろ。

というスタンスも十分アリってことですよ。

2回目にアクセスした時は速くなっているわけですから、ネット回線の一時的な不調と切り分け出来ないレベルだと思います。

しかし、我慢作戦では元も子もありませんから、真面目に技術的対処方法をご紹介します。
それは、Ajaxを使用することです。

Ajax作戦のカラクリ

GAEのスピンアップ問題から逃れることは出来ません。
そこでAjaxが活躍するのです。

  1. 先にHTMLファイルや画像などの静的コンテンツを表示する。
  2. 表示直後、OnLoadでAjax起動。くるくるダイアログを表示しつつ、非同期通信で動的コンテンツを取得。
  3. Ajaxにより動的コンテンツを表示。

この三段構えで表示することで、体感的に速く表示されるようになります。

1.静的コンテンツ表示

実はですね、GAEというのは、「Javaファイルが置かれているサーバ」と「HTMLや画像など静的ファイルが置かれているサーバ」は別々なのです。

そして、スピンアップが発生するのはJavaが置かれているサーバのみ。
HTML、CSS、JS、画像ファイルなど、静的ファイルの表示だけであればスピンアップは発生しないのです。

よって、①は常に超高速で表示されます。

これがAjax作戦の最大の秘訣です。

2.非同期通信

Ajaxの非同期通信によって、Javaにアクセスして内容を動的に表示します。
ここでスピンアップが起きるので、くるくるダイアログが10秒近く表示されていることになります。

つまり、トータルで待たされている時間は全く変わらないわけです。

ただ、①の時点で枠組み部分は表示済みになっており、処理中を意味する「くるくるダイアログ」も表示されていますので、
ホワイトアウト状態と比較すれば、待たされている人のストレスがは劇的に軽減されます。

3.描画処理

バックエンドの非同期通信でデータを取得しましたら、画面に出力します。


これにて画面が無事に表示出来ました。
これがGAE界で主流になっているAjax戦術の概要です。


Ajaxスキル必須


はい、ここでお分かりになられたかと思います。

Ajax作戦では、初期表示の際には静的ファイルであるHTMLを使用して表示します。
よって、jspは使用出来ません。
システム全体がAjaxに完全対応しなければならないのです。

上記には「我慢作戦という選択肢もある」と書きましたが、実際の所、GAE界ではこのAjax作戦が支配的なシェアを持っています。
GAE開発では、Ajax作戦が最適解であると言い切ってしまって良いでしょう。

つまり、開発者には「Javaスキル」と「Ajaxスキル」の両方が求められるわけです。

  • GAE開発は、JavaとAjaxの両方のスキルを持っていることが必須!!

プルダウンの中身を差し替えるだけみたいな粗末なAjaxではありません。
画面全体がAjax状態。
技術者はフルAjaxを実現するスキルを持っていなければなりません。


私はこの、「技術者の要求するスキルハードルの高さ」がGAE最大のネックだと思っています。
JavaとAjax、両方に精通している技術者というのは中々いません。


一般に、Javaというのは業務用アプリで多く使われる傾向にあります。
業務用アプリではAjaxは出番が少ないのです。

逆にAjaxが多く使用されるのはエンドユーザ向けシステム、例えばSNS辺りでしょうが、ああいうのはサイクルの速いスクリプト言語で書かれている事が常です。

つまり、GAE開発に必要とする「Java」と「Ajax」を両方揃えている技術者というのはレアケースということになります。


一応、「Android + HTML5のハイブリッドアプリ」の開発経験者なら期待出来る所ですが、それも技術者全体から見れば少数派でしょうし……。


「Java × Ajax」、これは意外にレアなのです。


終わりに

GAE最大の問題である「スピンアップ」について検証を重ねるうちに、
徐々にGAEの癖というものが分かってきましたね。

GAEは、普通のJavaWebシステム開発とは明らかに違う点が、確かにあります。

この為、GAE開発を行っている会社というのは、GAE専門特化型になっているケースが多いように見受けられますね。
スペシャリスト型でなければキツいのでしょう。

そんな、気軽に使うにはちょっとハードルの高いGAEですが、
次回はそれの有効活用法について検討したいと思います。