「PHPの開発環境を構築する」シリーズの第4回です。今回はXAMPPのPHP環境にPHPUnitをインストールし、またEclipseからPHPUnitのテストを実行できるMakeGoodというプラグインを組み込みます。そして実際にテストを実行してみます。
(2015年3月3日修正:Windows 8.1+Pleiades All in One Eclipse 4.4 Lunaの環境とComposerにてインストールした直近の環境に合わせて、大幅に修正しました。尚、画面のキャプチャの多くは2013年11月のままです。実際と異なる場合があります。)
前提条件
本稿は「PHPの開発環境を構築する(その1):「Pleiades All in One」のインストール」に記載した通りに設定しました、以下の環境を対象に記載しております。各ソフトウェアのバージョンが異なる場合は動作が異なると思いますのでご留意ください。またパス等も各位の環境に合わせて読み替えをお願いいたします。
- OS:Windows8.1 64bit
- 環境:Pleiades All in One、Eclipse 4.4 Luna、PHP full(以下、pleiades php 4.4)
- Eclipse Platform Version: 4.4.0
- ApacheFriends XAMPP Version 1.8.2
- Apache 2.4.4
- MySQL 5.5.32
- PHP 5.4.19
- phpMyAdmin 4.0.4.1
- XAMPP Control Panel Version 3.2.1
pleiades php 4.4に付属のPDT(ver.3.3.0)では、デバッグモードでのステップ実行の際に、実行行がエディタに反映されないという不具合がありました。ステップ実行をする場合は、以下のようにPDTのアップデートが必要です。
- メニューより「ヘルプ>更新の確認」を選択する。
- 「選択をすべて解除」をクリックしてチェックした後、「PHP開発ツール (PDT)」をチェック」。(2014年12月22日現在、最新はver.3.3.2)
- 「次へ」をクリックし、以下ウィザードに従ってアップデートする。
本稿を記述の時点での各ツールのバージョンは、以下になります。
- PHPUnit 4.5.0
- phpunit-skelgen 2.0.1
- MakeGood 3.1.1
ツールのバージョンが異なる場合も、挙動が異なることは大いに考えられます。
以降のレポートは、プロジェクトの作成が済んでおり、テストドライバを格納するフォルダが作成されていることが前提です。「テストの実行」の節では、テスト対象のクラスが入ったphpファイルがあることが前提となります。
実行可能ファイルの確認
Pleiades PHPのEclipse+PDTでは既に実行可能ファイルとデバック環境の設定がなされています。(本節はスキップして頂いて構いません。)
環境が異なるとこれらが用意されていないかもしれません。本章にこれらの確認を示します。もしこれらが設定されていませんのでしたら、設定をお願いします。
上部メニューより「ウィンドウ>設定」を選択します。すると設定ダイアログが開きます。
左側メニューより「PHP>PHP実行可能ファイル」を選択します。
右側ペインにて、PHP実行可能ファイルがあることを確認します。
Pleiades PHPのデフォルトでは上のようになっています。
デバック環境の確認
同じく設定ダイアログの左側メニューより、「PHP>デバッグ」を選択します。
上のように設定されています。確認終了後、設定ダイアログを閉じます。
(2014年12月22日追記:pleiades php 4.4の場合は、デバッガーがXDebug固定であったり、画面が異なります。同じような情報が表示されていればOKでしょう。)
またメインメニューの「プロジェクト>プロパティー」にて開く、プロパティーダイアログの「PHPデバッグ」のペインでもデバッグ環境の設定をみることができます。
テスト環境の構築
Pleiades PHPにPHPUnitとMakeGoodをインストールし、動作するように設定します。
PHPUnitのインストール
PHPUnitとphpunit-skelgenをインストールします。
その手順は別稿「Composerによるツールのインストール」をご参照下さい。
MakeGoodのインストール
Eclipseを起動し、上部メニューから「ヘルプ>新規ソフトウェアのインストール」を選択します。
「作業対象」に「http://eclipse.piece-framework.com/」を入力し、その右の「追加」をクリックします。
「名前」は空白のままで構いませんので、「OK」をクリックします。
「MakeGood」を選択し、下方の「次へ」をクリックします。
インストールの確認をして「次へ」をクリックします。
ライセンスを確認し、「使用条件の条項に同意します」をチェックして、「完了」をクリックします。
証明書を信頼するかどうかのダイアログが開きます。「すべて選択」をクリックしてチェックを入れてから、「OK」をクリックします。
再起動のダイアログが表示されるので、「OK」をクリックします。
再起動したら、メニューより「ウィンドウ>ビューの表示>その他」を選択します。
MakeGoodを選択して「OK」をクリックします。すると下のペインにMakeGoodビューが追加されます。
(2015年3月3日:現在は、上のような「PHPUnit_Framework_TestCase クラスが利用できません。」というエラーが表示はないと思います。以前は、Pearへのパスの設定を記述していましたが、それらも削除しました。)
プリロードスクリプトの作成
以下の様なスクリプトを作成します。ここでは、プロジェクトディレクトリ直下に「preload.php」という名前で作成することにします。
<?php require_once 'C:\pleiades\xampp\php\vendor\autoload.php';
2行のパスは、Composerにて作成されたディレクトリ、vendorの中にあるautoload.phpまでのパスです。
(次節にて、この「preload.php」までのパスの設定をします。これの代わりにautoload.phpを直接指定しても良さそうですが、絶対パス、相対パスでもうまく行きませんでした。)
MakeGoodの設定
次にプロジェクトにMakeGoodの設定をします。PHPエクスプローラーにてプロジェクトが選択された状態で、メニューより「プロジェクト>プロパティー」を選択します。するとプロパティーダイアログが開きます。
左側メニューより「MakeGood」を選択します。
「テストフォルダー」の右の「追加」をクリックします。
テストドライバのフォルダを選択し、「OK」をクリックします。
さらに「プリロードスクリプト」に、先ほど作成したpreload.phpを設定します。
以上でMakeGoodの設定は完了です。プロパティーのダイアログも「OK」をクリックして閉じます。
phpunit-skelgenの組み込み
phpunit-skelgenをEclipseから呼び出せるように設定します。
メニューより「実行>外部ツール>外部ツールの構成」をクリックします。
「プログラム」が選択された状態で、左上のをクリックします。すると「プログラム」の下に「新規構成」が作成されます。
右側のペインにて名前を「phpunit skelgen」のように入力します。また「メイン」タブにて以下の設定をします
- ロケーション :
C:\pleiades\xampp\php\vendor\bin\phpunit-skelgen.bat
- 作業ディレクトリ :
${project_loc}
- 引数 :
generate-test ${string_prompt:namespace\class} ${selected_resource_loc}
これらは、テスト対象のクラスからテストドライバを生成するための設定です。(引数のgenerate-test
の替りにgenerate-class
を指定すると、逆にテストドライバからソースのスケルトンが生成できるようです。)
続いて「リフレッシュ」タブをクリックします。
「完了時にリソースをリフレッシュ」にチェックをして、「選択されたリソースを含むフォルダー」を選択します。
続いて「共通」タブをクリックします。
「お気に入りのメニューに表示」の「外部ツール」にチェックを入れ、「適用」をクリックします。
以上でphpunit-skelgenの組み込みが終了しました、「閉じる」をクリックしてダイアログを閉じます。
テストの実行
(2015年3月3日現在、私は既にphpunit-skelgenは使っていません。以下の記事は2013年11月のままですので、phpunit-skelgenについての記載には現状と異なる場合があるかもしれません。)
ではテストを実行してみましょう。
テストドライバがないのでphpunit-skelgenでスケルトンを作成します。尚phpunit-skelgenが対応しているのはクラスのみなので、関数がテスト対象の場合は手動で作成します。
テストドライバを手動で作成する方、すでにテストドライバがある方は次節をスキップしてください。
テストドライバのスケルトンの作成
PHPエクスプローラーより、テスト対象のクラスの入ったphpファイルをクリックして選択します。そしてメニューより「実行>外部ツール>1 phpunit-skegen(1)」を選択します。
クラス名を訪ねるダイアログが表示されますので、テスト対象のクラス名を入力し、「OK」をクリックします。
すると選択したファイルと同じフォルダに「(クラス名)Test.php」というファイルができます。これがテストドライバのスケルトンになります。
このファイルを右クリックし、「リファクタリング>移動」を選択してテストドライバ格納フォルダ以下に移動します。
テストの実行
PHPエクスプローラーよりテストドライバをダブルクリックしてコードを表示してやると、テスト対象のクラスのNewがエラーになっています。そこでクラス宣言より上(namespaceよりは下)に、require_onceをかいてテスト対象を読み込んであげます。
require_once '(テスト対象へのパス)';
保存すると、問題ビューにエラーが表示されます。
何事かと思いますが、保存したときにMakeGoodが自動的にテストを実行して、未実装のテストケースのmarkTestIncompleteメソッドをエラーとして表示したようです。(問題ビューだと「エラー」扱いですが、MakeGoodビューでは、テストの失敗ではなく、エラー扱いです。)
とりあえず一つのケースだけ実装して、保存します。するとテストが自動的に走ります。
MakeGoodビューを見ると、成功が1になっています。
またビューを拡大して「テスト結果」を見ると、成功したケースの左にはチェックが付いています。失敗が×、エラーが!になりますので、コーディングフェイズでは×がないことを目標にします。また×と!はコードビューにも表示されます。
デバッグ
必要なテストケースを作成し、いらないテストケースは削除してやってテストドライバを完成します。
MakeGoodビューを見ると、エラーが幾つかと失敗が一つありました。この失敗をデバッグしてみます。
デバッグの設定
まずデバッグ実行の際に最初の行で停止するのは面倒なので、その設定を外します。既にそうなっている方は本節をスキップしてください。
メニューから「ウィンドウ>設定」を選択して設定ダイアログを開き、左側から「PHP>デバッグ」を選択して「PHPデバッグ」を表示させます。(あるいはデバッグ パースペクティブの設定ボタン。)
「最初の行でブレーク」のチェックを外し、「OK」をクリックして設定を終了します。
ブレークポイントの設定
コードビューでテストドライバを見ると、失敗のassertに×がついています。
そこでテスト対象のメソッドを呼び出している行にブレークを張ります。
MakeGoodビューのツールバーにて、まず(テストをデバッグする)をクリックして押下した状態のデバックモードにします。続いて(失敗したテストの再実行)をクリックします。
しばらくしてデバック パースペクティブに切り替わり、設定したブレークポイントで停止します。後はステップインしてメソッドに入り、変数の値を見ながらステップ実行して欠陥を探ります。(ちなみに例示のテスト失敗は、テストドライバのメソッドのコールにて、戻り値を格納する’$b_r = ‘を書いていませんでした。orz)
テストの実行をクリックしてからブレークするまで案外時間がかかりますので、気長にデバッグします。
デバッグが終了したら、をクリックし押下されていない状態にもどします。(テストの実行スピードが若干速くなるかもしれません。)
全てのテストが成功したら、とりあえずテストフェイズ完了です。
テストの手動実行
保存時にテストが自動実行されないようにすることもできます。
MakeGoodのツールバーから(継続的テストを設定する)をクリックします。するとボタンがに変わり、テストの自動実行がなされなくなります。もう一度クリックするとボタンはに戻り、テストの自動実行がなされるようになります。
テストの手動実行は、以下の操作によって行います。
- MakeGoodビューのツールバーのの中の任意のボタンを押す。
- PHPエクスプローラーにて、フォルダやテストドライバを右クリックして表示されるメニューより「テストの実行」や「すべてのテストの実行」を選択する。
課題
phpunit-skelgenによってテストドライバのスケルトンが生成できますが、生成されたソースの以下の点が気に入りません。
- クラスを対象にしたテストしか生成できない。関数のテストケースも生成してほしい。
- クラス名を指定するのではなく、ソースファイル名さえ指定すれば、その中の関数・クラスのテストケースを生成するようにすればよい。そうするとソースとテストドライバが一対一で対応する。
- require_onceくらいは出力してほしい。
- インデントはスペースでなくタブでしてほしい。
- シナリオ・ベースのテストをするので、最初から全てのメソッドのスケルトンを有効にしないでほしい。
Javaのようなクラスベースの言語であれば1,2点目はよいのかもしれませんが、PHPでは致命的だと思います。
また最後の点に関して、私は最初にシナリオのテストケースを作って実行し、カバレッジをみて後から例外処理のテストケースを追加するスタイルです。全てのメソッドについてスケルトンを出力してくれてもよいのですが、後から必要に応じて有効化できるように、コメントアウトしておいてほしいです。
(2014年3月12日 追記)
unlinkなのど関数内で例外が発生した場合は、ドライバの関数内でcatchしないとそのまま関数を抜けてしまい、テストを完了していないのにmakegoodビューでは緑のチェックになるようです。(PHPUnitの仕様?)
ちゃんと関数仕様を読んで、エラーが発生する関数には、’@’を付けるかtry,catchを書いたほうがよさそうですね。
まとめ
Eclipse+PDT環境にPHPUnitとMakeGoodを組み込み、単体テストができるようになりました。しかしPHPUnit_SkeletonGeneratorはいまいちです。
(テストドライバのスケルトンを生成するスクリプトの公開もそのうちに。。。)
(その5)は、PHPの性的解析ツールであるPHPMDを試してみます。