Fixureテストサンプル

CakePHP1.2では、Fixtureによるテストデータのロード機能があるので、使ってみます。テスト環境の動作がRailsともまた一味違うようで、大いにハマりました。

CakePHP1.2流Fixure

前回ちょっとだけテストケース作りましたが、やっぱりRailsのFixtureのような機能がほしい。

  Testing Models with CakePHP 1.2 test suite

上の記事が詳しく、基本的にマネすればいいのですが、ハマりポイントもアリ。まだalpha版ってことなので、目くじら立てるほどでもないけど、どう動いてるのかわからず、ややウザな検証が必要でした。

ということで、ブログチュートリアルで作ったPostをテストするメモ。
CakePHPバージョンは、1.2.0.5146alpha です。

■app/models/Post.php

<?php
class Post extends AppModel {
 var $name = "Post";
}
?>

コンフィグレーションの件

■app/config/database.php

class DATABASE_CONFIG {
 var $default = array(
  'database' => 'cake',
 );
 var $test = array(
  'database' => 'cake_test',
 );
}

まず、app/config/database.phpの設定ですが、$testの方は「設定されていれば使う・されていなければ使わない」という、ゆるーい仕様です。$testを消しても、$defaultの方でテストできてしまいます。

どちらのDBを使うにしても'test_suite_'という固定のプレフィックスがついたテスト用テーブルが自動作成されるので、既存テーブルを壊したりしません。※Railsユーザーには違和感ポイント。Fatalとかでテストが止まらない限り、気づかない...

Fixtureを使ったテストケース

■app/tests/cases/models/PostTestCase.php

<?php
loadModel('post');

//Postにテスト用の設定をオーバライドする。
class PostTest extends Post {

 var $name = 'Post';
 //→ 使うテーブル名は'test_suite_posts'になる。

 //$testまたは$defaultを使う設定。
 var $useDbConfig = 'test_suite';
 //→ $tablePrefixが自動で'test_suite_'に。

 //または、テストで使うDBを明示できる
 // var $useDbConfig = 'test'; //database.phpで定義した名前
 // var $tablePrefix = 'test_suite_'; //固定

}

class PostTestCase extends CakeTestCase {

 //PostFixture.php(下記参照)でデータロード
 var $fixtures = array( 'post' );

 function testSomething() {
   $this->Post = new PostTest(); //new Post() ではなく
   $this->Post->save(array('id'=>'1','title'=>'aaaaaa'));
   $this->assertTrue($this->Post->findById(1));
 }
}
?>

Postをそのままテストすると、$default.postsテーブルを使ってテストが走ってしまいます。$useDbConfig = 'test_suite'と上書きすると、($test or $default).test_suite_postsテーブルでテストが走ります。
それで、あとは、継承クラスに対してテストコードを書きます。

Fixtureがやってること

■app/tests/fixtures/PostFixture.php

<?php
class PostFixture extends CakeTestFixture {

 //test_suite_postsというテーブル名で
 var $name = 'Post';

 //$default.postsからスキーマをコピー
 var $import = array('model'=>'Post');

 //または、レコードもコピー
 //var $import = array('model'=>'Post', 'records'=>true);

 /* または、コピーではなく自作もできる。
 var $fields = array(
  'id' => array('type' => 'integer', 'key' => 'primary'),
  'title' => array('type' => 'string', 'length' => 255, 'null' => false),
  'body' => 'text',
  'created' => 'datetime',
  'updated' => 'datetime'
 );
 var $records = array(
  array ('id' => 1, 'title' => '11111'),
  array ('id' => 2, 'title' => '22222')
 );
 */

}
?>

$defaultの既存のテーブルを$importすると、テスト用のテーブルとしてテーブルのコピーを作成します。$importの代わりに、(Rails Migrateの要領で)自分でスキーマを作って$recordsを挿入することもできます。

$importしたテーブルに$recordsを書き込めるとサイコーなのですが、残念ながら現時点では動作しませんでした。
(※挿入はしてるんだけど、テストメソッドが走る直前に消えてしまう。フックの順番が間違っているようだ・・・)


コメント

コメントしてください
お名前:
入力しなければ「匿名さん」。20字以内。

メール:
入力しても表示しません

URL:
入力すればリンクが貼れます


コメント: