Doctrineはユニットテストを使用するプログラムでテストされます。Wikipediaでユニットテストの[http://en.wikipedia.org/wiki/Unit_testing 記事]を読むことができます。
テストを実施する¶
Doctrineに搭載されるテストを実施するにはライブラリフォルダだけでなくプロジェクト全体をチェックアウトする必要があります。
/path/to/co/doctrine
Doctrineのチェックアウトのディレクトリに移動します。
$ cd /path/to/co/doctrine
次のファイルとディレクトリが見えます。
CHANGELOG COPYRIGHT lib/ LICENSE package.xml tests/ tools/ vendor/
Tip
認識できるテストの失敗ケースが用意されるのはめったにありません。もしくはDoctrineには後のバージョンまでコミットできないバグ修正もしくは強化リクエスト用のテストケースが存在します。もしくは単に問題の修正コードが存在しないので失敗のままのテストもあります。Doctrineのそれぞれのバージョンでどれだけの数のテストの失敗ケースがあるのかメーリングリストもしくはIRCでたずねることができます。
CLI¶
コマンドラインでテストを実施するには、php-cliをインストールしなければなりません。
``/path/to/co/doctrine/tests``フォルダに移動して``run.php``スクリプトを実行します:
$ cd /path/to/co/doctrine/tests $ php run.php
これによってすべてのユニットテストを実行しているときに進行バーが出力されます。テストが終了したとき何が成功し何が失敗したのか報告されます。
CLIには特定のテスト、テストのグループを実施するもしくはテストスィートの名前でテストをフィルタリングするためのオプションがありあす。これらのオプションを確認するために次のコマンドを実行してください。
$ php run.php -help
次のように個別のテストグループを実行できます:
$ php run.php –group data_dict
ブラウザ¶
``doctrine/tests/run.php``に移動すればブラウザでユニットテストを実施できます。オプションは変数``_GET``を通して設定できます。
例:
http://localhost/doctrine/tests/run.phphttp://localhost/doctrine/tests/run.php?filter=Limit&group[]=query&group[]=recordCAUTION テストの結果が環境に大きく左右されることがあることにご注意ください。例えば``php.ini``の``apc.enable_cli``ディレクティブが0に設定されている場合追加テストが失敗することがあります。
テストを書く¶
テストスィートを書き始めるとき、``TemplateTestCase.php``をコピーすることから始めます。サンプルのテストケースは次の通りです:
class Doctrine_Sample_TestCase extends Doctrine_UnitTestCase {
public function prepareTables() { $this->tables[] = “MyModel1”; $this->tables[] = “MyModel2”; parent::prepareTables(); }
public function prepareData()
{
$this->myModel = new MyModel1();
//$this->myModel->save();
}
public function testInit()
{
}
// This produces a failing test
public function testTest()
{
$this->assertTrue($this->myModel->exists());
$this->assertEqual(0, 1);
$this->assertIdentical(0, '0');
$this->assertNotEqual(1, 2);
$this->assertTrue((5 < 1));
$this->assertFalse((1 > 2));
}
}
class Model1 extends Doctrine_Record { }
class Model2 extends Doctrine_Record { }
NOTE モデルの定義はテストケースファイルに直接含まれるもしくはこれらは``/path/to/co/doctrine/tests/models``に設置可能です。そうすればこれらはオートロードされます。
テストを書く作業を終えたら必ず``run.php``に次のコードを追加してください。
$test->addTestCase(new Doctrine_Sample_TestCase());
run.phpを実行するとき新しい失敗ケースが報告されます。
チケットテスト¶
Doctrineにおいてtracに報告される個別のチケット用のテストの失敗ケースをコミットするのが慣行になっています。``/path/to/co/doctrine/tests/Ticket/``フォルダで見つかるすべてのテストケースを読むことでこれらの手数とケースは自動的にrun.phpに追加されます。
CLIから新しいテストケースのチケットを作成できます:
$ php run.php –ticket 9999
チケット番号9999がまだ存在しない場合空白のテストケースクラスが``/path/to/co/doctrine/tests/Ticket/9999TestCase.php``に生成されます。
class Doctrine_Ticket_9999_TestCase extends Doctrine_UnitTestCase {
}
テスト用のメソッド¶
Identicalをアサートする¶
ロジックがより厳密で2つの値の比較に``===``を使用すること以外``assertIdentical()``メソッドは``assertEqual()``と同じです。
// … public function testAssertIdentical() {
$this->assertIdentical(1, ‘1’); } // …
NOTE 1番目の引数の数字の1がPHPの整数型としてキャストされるのに対して2番目の引数の数字の1はPHPの文字列型としてキャストされるので明らかに失敗します。
モックドライバ¶
Doctrineはsqlite以外のすべてのドライバ用のモックドライバを使用します。次のコードスニペットはモックドライバの使い方を示します:
class Doctrine_Sample_TestCase extends Doctrine_UnitTestCase {
public function testInit() { $this->dbh = new
Doctrine_Adapter_Mock(‘oracle’);
this->conn = Doctrine_Manager::getInstance()->openConnection(this->dbh);
} }
クエリを実行するときこれらは本当のデータベースに対して実行されません。代わりにこれらは配列に収集され実行されたクエリとそれらに対するテストのアサーションを分析できます。
class Doctrine_Sample_TestCase extends Doctrine_UnitTestCase { //
…
public function testMockDriver()
{
$user = new User();
$user->username = 'jwage';
$user->password = 'changeme';
$user->save();
$sql = $this->dbh->getAll();
// 探しているクエリを見つけるためにSQL配列を出力する
// print_r($sql);
$this->assertEqual($sql[0], 'INSERT INTO user (username, password) VALUES (?, ?)');
}
}
テストクラスのガイドライン¶
すべてのクラスはTestCaseと同等のものを少なくとも1つ持ち``Doctrine_UnitTestCase``を継承します。テストクラスはクラスもしくはクラスのアスペクトを参照し、それに応じて命名されます。
例:
テストメソッドのガイドライン¶
メソッドはアジャイルなドキュメントをサポートし何が失敗したのか明確にわかるように名付けられます。これらはテストするシステムの情報も提供します。
例えばメソッドのテスト名として``Doctrine_Export_Pgsql_TestCase::testCreateTableSupportsAutoincPks()``は良い名前です。
テストメソッドの名前は長くなる可能性がありますが、メソッドの内容は長くならないようにすべきです。複数のアサート呼び出しが必要なら、メソッドを複数のより小さなメソッドに分割します。ロープもしくは関数の中にアサーションがあってはなりません。
NOTE 共通の命名規約として使われる``TestCase::test[methodName]``はDoctrineでは**されません**。ですのでこのケースでは``Doctrine_Export_Pgsql_TestCase::testCreateTable()``は許可されません!
まとめ¶
Doctrineのようなソフトウェアのピースにとってユニットテストは非常に重要です。これ無しでは、変更によって既存の作業ユースケースに悪影響があるのかを知るのは不可能です。ユニットテストのコレクションによって変更が既存の機能を壊さないことを確認できます。
次に[doc improving-performance パフォーマンスを改善する]方法を学ぶために移動します。
