そうだ、コアを読もう

プログラミングにおいて一番重要なことは何だろう?

その問いの答えはそれぞれの人で違うと思う。

企画、設計、実際のコーディング…。

しかし、製品として世に出す以上、やはりデバッグが一番大事なのではないだろうか。

 

 

現在開発している製品はフレームワークCakePHP を利用している。

CakePHP にはデバッグを自動化するための仕組みが組み込まれている。

もちろん自動化といっても、テストするための指示はある程度コーディングしなければならない。

bake やら Jenkins やらで結構お手軽に出来るので、その辺は調べれば山ほど出てくる。

 

今回はフィクスチャと呼ばれるテストデータの記述で躓いた。

CakePHP命名規則があり、ファイル名、DBのテーブル名、クラスなど、が名前によって自動的に連携される。

逆に言えばそれに従わないファイル名やテーブルを使おうとしたら、苦労するという話で、実際に苦労した。

 

たとえば person というモデルがあった場合、テーブル名は複数形の people となる。

が、ここであえて persons と言うテーブルを使いたいという、ひねくれ者がいたとする。

この場合モデルでは、

class Person extends AppModel {

    public $useTable = 'persons';

...

}

 とすればいい。

 

ではフィクスチャではどうするのだろう?

検索してみたが、探し方が悪いのか、全く情報が見つからなかった。

開発中なんだし、命名規則どおりにテーブル名を変えてしまえばすぐ済む話だが、設計者が自分じゃないので非常に面倒くさい複数人が携わるプロジェクトでは意外と融通が利かないこともあるのだ。

フレームワーク使ってるのに命名規則に従わないなんて馬鹿なの?

 

モデルで命名規則外の指定を許しているのだから、当然フィクスチャにもあるはずだ。

ネットで調べて見つからないなら、直接フレームワークに聞いてみればいい。

lib/Cake/TestSuite/Fixture/CakeTestFixture.php

の53行目に発見。

public $table = null;

名前からしてテーブル名っぽい。

しかし実際にそうなのだろうか?

もうちょっと読み進めてみよう。

すると181行目に以下の記述を発見。

if (!isset($this->table)) {

    $this->table = Inflector::underscore(Inflector::pluralize($this->name));

}

ほほう。

$this->table が指定されていない場合、 $this->name を複数形にして(Inflector::pluralize)、小文字のアンダースコア(_)で結合した形にする(Inflector::underscore)としている。

Inflector クラスは CakePHP命名規則に関する変換などを行うクラスである。

そして $this->name とは何ぞや?とファイルの先頭に戻ると、

/**

 * Name of the object

 *

 * @var string

 */

    public $name = null;

とあり、オブジェクト名っぽいことがわかり、実際に __construct() では、

if ($this->name === null) {

    if (preg_match('/^(.*)Fixture$/', get_class($this), $matches)) {

        $this->name = $matches[1];

    } else {

        $this->name = get_class($this);

    }

}

 と、 $this->name が指定されていないときにファイル名か、クラス名から取得している。

PersonFixture だった場合、特に何も指定していないと、 $this->name = Person となる。

そして $this->table はその複数形のアンダースコアなので people に決定されることになる。

実際に両方指定せずに PersonFixture を作成してテストを実行してみると people テーブルが作成されていた。

と言うことで結論。

命名規則以外のフィクスチャを使うときは、 public $table を指定してやる。

 

今回の環境:

PHP 5.5.10

CakePHP 2.4.6