search
LoginSignup
13

More than 5 years have passed since last update.

posted at

updated at

フィクスチャの管理を少しでもラクにする

継続的インテグレーションには欠かせないテストの中で「う~ん」と、ちょっとだけ何とかならないものか、と思ったのがフィクスチャの管理。

なにを何とかしたいと思ったかというと・・・

スキーマ情報を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を管理する

フィクスチャファイルは、以下の情報を記述します。

  1. テーブル構造
  2. フィクスチャデータ

このうち、テーブル構造をschema.phpの記述を流用しラクします。

schema.phpを読み込むモードを作る

フィクスチャは$importを指定すると、モデルやテーブルを指定しスキーマやデータを取得するモードが元々備わっていますので、ここにスキーマファイルを読み込むモードを追加します。
テスト(Testing) — CakePHP Cookbook 1.3 ドキュメント/テーブルの情報とレコードの読み込み

以下のコードをapp_test_fixtures.phpとしてapp/tests/lib/ディレクトリに保存します。

app_test_fixture.php
<?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モデルのフィクスチャファイルです。

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
13