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.php

  • http://localhost/doctrine/tests/run.php?filter=Limit&group[]=query&group[]=record

    CAUTION テストの結果が環境に大きく左右されることがあることにご注意ください。例えば``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 {

}

テスト用のメソッド

Equalをアサートする

// ... public function test1Equals1() { $this->assertEqual(1, 1); } //

...

Not Equalをアサートする

// ... public function test1DoesNotEqual2() { $this->assertNotEqual(1,

2); } // ...

Identicalをアサートする

ロジックがより厳密で2つの値の比較に``===``を使用すること以外``assertIdentical()``メソッドは``assertEqual()``と同じです。

// ... public function testAssertIdentical() {

$this->assertIdentical(1, ‘1’); } // ...

NOTE 1番目の引数の数字の1がPHPの整数型としてキャストされるのに対して2番目の引数の数字の1はPHPの文字列型としてキャストされるので明らかに失敗します。

Trueをアサートする

// ... public function testAssertTrue() { $this->assertTrue(5 > 2); }

// ...

Falseをアサートする

// ... public function testAssertFalse() { $this->assertFalse(5 < 2); }

// ...

モックドライバ

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_Record_TestCase``は``Doctrine_Record``クラスを指し示すので良い名前です。
  • ``Doctrine_Record_State_TestCase``は``Doctrine_Record``クラスの状態を指し示すのでこれも良い名前です。
  • ``Doctrine_PrimaryKey_TestCase``は一般的すぎるので悪い名前です。

テストメソッドのガイドライン

メソッドはアジャイルなドキュメントをサポートし何が失敗したのか明確にわかるように名付けられます。これらはテストするシステムの情報も提供します。

例えばメソッドのテスト名として``Doctrine_Export_Pgsql_TestCase::testCreateTableSupportsAutoincPks()``は良い名前です。

テストメソッドの名前は長くなる可能性がありますが、メソッドの内容は長くならないようにすべきです。複数のアサート呼び出しが必要なら、メソッドを複数のより小さなメソッドに分割します。ロープもしくは関数の中にアサーションがあってはなりません。

NOTE 共通の命名規約として使われる``TestCase::test[methodName]``はDoctrineでは**されません**。ですのでこのケースでは``Doctrine_Export_Pgsql_TestCase::testCreateTable()``は許可されません!

まとめ

Doctrineのようなソフトウェアのピースにとってユニットテストは非常に重要です。これ無しでは、変更によって既存の作業ユースケースに悪影響があるのかを知るのは不可能です。ユニットテストのコレクションによって変更が既存の機能を壊さないことを確認できます。

次に[doc improving-performance パフォーマンスを改善する]方法を学ぶために移動します。