継続的インテグレーションには欠かせないテストの中で「う~ん」と、ちょっとだけ何とかならないものか、と思ったのがフィクスチャの管理。
なにを何とかしたいと思ったかというと・・・
スキーマ情報を2箇所で管理する
CakePHPではテーブル構造を管理するファイルとしてスキーマファイルが存在します(app/config/schema/schema.php)。これとは別に、全く同じ書式でテーブル構造を管理しなくてはいけないフィクスチャ(app/tests/fixtures/*_fixture.php)があります。
この管理をラクする為に、株式会社うるるで実践している方法を公開しちゃいます。
schema.phpを管理する
schema.phpは本番環境や開発環境からのダンプデータを用いてデータベースを構築する以外に、真っさらな状態から環境を構築したり、また、構造をリポジトリで管理・記録するために、構造が変更になった場合は、更新する様に義務付けています。
schema.phpは手動での更新を推奨しておらず、CakePHPのschemaシェルによって更新を行います。それほど頻繁に更新しないため、記述形式を覚えるのが難しく、誤った記述をしてしまうことがあるのが主な理由です。
更新手順
(1) テーブルに対し、直接alter文で構造を変更します。
(2) 前述のシェルを実行しschema.phpを更新します。
$ php /path/to/cakephp/cake.php schema generate -f
Schema file exists.
[O]verwrite
[S]napshot
[Q]uit
Would you like to do? (o/s/q)
[s] >
o
をタイプし、schema.phpファイルを上書きします。
(3) 必要に応じてgit add
に--patch
オプションを付け変更箇所のみをステージングしてコミットします。
なぜ、schema.phpの管理について解説の必要があったのか。
それは、フィクスチャの管理をラクにするために、このschema.phpを利用するからです。
モデル名_fixture.phpを管理する
フィクスチャファイルは、以下の情報を記述します。
- テーブル構造
- フィクスチャデータ
このうち、テーブル構造をschema.phpの記述を流用しラクします。
schema.phpを読み込むモードを作る
フィクスチャは$import
を指定すると、モデルやテーブルを指定しスキーマやデータを取得するモードが元々備わっていますので、ここにスキーマファイルを読み込むモードを追加します。
テスト(Testing) — CakePHP Cookbook 1.3 ドキュメント/テーブルの情報とレコードの読み込み
以下のコードをapp_test_fixtures.php
としてapp/tests/lib/
ディレクトリに保存します。
<?php
class AppTestFixture extends CakeTestFixture
{
public function init()
{
if (isset($this->import) && is_array($this->import) && isset($this->import['schema'])) {
$name = $file = $path = $connection = $plugin = null;
if (empty($this->import['file'])) {
$this->import['file'] = 'schema.php';
}
if (strpos($this->import['file'], '.php') === false) {
$this->import['file'] .= '.php';
}
$file = $this->import['file'];
if (! empty($this->import['path'])) {
$path = $this->import['path'];
}
$Schema = & new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin'));
$this->fields = $Schema->load()->tables{$this->import['schema']};
unset($this->import);
}
parent::init();
}
}
フィクスチャファイルで指定する
実際のファイルを見ていただいた方が早いでしょう。
以下は、acoモデルのフィクスチャファイルです。
<?php
require_once TESTS . 'lib' . DS . 'app_test_fixture.php';
class AcoFixture extends AppTestFixture
{
public $name = 'Aco';
public $import = array('schema' => 'acos');
public $records = array();
}
先ほどのapp_test_fixture.php
を読み込み、$import
を指定します。指定時には、キーにschema
を必ず指定し、値はテーブル名を指定します。モデル名ではないので、注意してください。
public $import = array('schema' => 'テーブル名');
これでスキーマの変更による最も面倒なスキーマのカラムの追加をラクにすることができました。
おわりに
さらに、うるるではテストをはやくするために、テスト実施時に可能ならMEMORYエンジンでテーブルを作成する様に改造されていたりしています。
宣伝(๑❛ᴗ❛๑)
エンジニアまっとります!
うるるでは、現在、エンジニアを募集しております。CakePHPを中心に開発環境やテスト環境も充実しております!ご興味のある方は是非ご覧ください。
上場準備突入中ベンチャーで、自社サービスを今どきな開発スタイルでやりたいWebエンジニア
http://www.green-japan.com/job/21292
「CakePHPで学ぶ継続的インテグレーション」
CakePHPを使った題材で、CakePHPアドベントカレンダーをご覧の方にはぴったり。もちろん、CakePHP以外のフレームワークでも十分に参考になる内容となっておりますので、こちらも合わせてご覧ください。
CakePHPで学ぶ継続的インテグレーション
http://www.amazon.co.jp/dp/4844336789