Db_Fixture をリリースしました

データベース周りのテストを実施するのに、 テストデータを突っ込むのがめんどくさい。
RubyRuby on RailsPerlDBIx::Class では fixture という機能があるそうな。
予め用意したテストデータを記述したファイルを読み込んで、データベースに突っ込んでくれるアレ。


PHP で同じようなものが無いかと探したら、 PHPUnit で実現しているのを見つけた。

データベース関連のユニットテストを作成するもっとも手っ取り早い方法は、 PHPUnit_Extensions_Database_TestCase クラスを継承することです。 このクラスには、データベース接続を作成したり データベースにデータを送信したり、 テストの実行後にデータベースの中身を様々な形式のデータセットと比較したりする機能があります。

PHPUnit – The PHP Testing Framework

Zend Framework だとこんなんも見つけた

Zend_PHPUnit_Fixtures

Testing scaffolding for Zend Framework.

Used to help assist in keeping our test cases isolated.

GitHub - baphled/zend_phpunit_fixtures: Fixtures handling and management system, used to help build test cases within Zend Framework.

PHPUnit を使用している場合は良いんだろうけど、オレは PHPSpec を使いたいんじゃ!とかワタシは lime が良いのよ!とか言う人には優しくない。
テスティングフレームワークに依存しないのは無いのかと探したけど見つからなかったので作ってみた。

Db_Fixture

使い方

幾つかの規約があります。

  1. ディレクトリ構成
  2. PDO が使用できること
  3. 現在サポートしている形式は json 形式のみ
  4. PHP 組み込みの json 関数を使用できること
ディレクトリ構成

デフォルトではFixture ファイルを設置するディレクトリと同一の階層に config というディレクトリを設置し、その中に database.jsonというファイルを設置します。

 test
    |-- config
    |          `--  database.json
    `--testdata
                `--  test.json

database.json は以下の様に記述します。

{
  "dsn": "mysql:host=localhost;dbname=test;port=3306",
  "username": "test",
  "password": "testtest"
}

dsn は PDO の形式で記述します。
因にテストは MySQL だけでしか確認してないので、 PostgreSQLSQLiteOracle はどなたか確認して貰えると嬉しいです。

ファイル形式

現在 json 形式だけです。何故 yaml ではなく json かというと yaml を使用する場合、外部のライブラリが必要だから。
極力組み込みの機能だけで実現したかったのが理由です。
# いずれ csv 形式とか xml 形式も作るかもしれません。

Fixture の書き方

{
  "test1": {
    "auto_increment": "id",
    "row1": {
      "test_id": "1",
      "test1": "test",
      "created_at": "2009-03-20 20:00:00"
    }
  },
  "test2" : {
    "primary_key": ["test_id", "test2"],
    "row1": {
      "test_id": "1",
      "test2": "2",
      "created_at": "2009-03-20 20:00:30"
    }
  }
}

こんな感じで記述します。
test1, test2 がテーブル名です。
auto_increment は テーブルが auto increment やシーケンスを使用する際に設定します。
これを設定する事で、 データを挿入時に挿入した シーケンス番号を取得します。
primary_key も同様にデータ挿入時に、指定したカラムのデータを挿入時に記憶します。
これらは最後にデータを削除する際のキーとなります。
primary_key は配列形式で 複数のカラム名を指定できます。
# auto_increment は一つだけ


row1, row2 となっているのが挿入する行で、その下が各カラムとなります。
(row1, row2 というのは別に何の名前でも良い)
日時を入れる場合、 System.Date:Y-m-d H:i:s と書くとシステム時間が挿入されます。
# : の右側は date() の書式です。

呼び出し方

<?php
require_once 'Db/Fixture.php';
$obj  = Db_Fixture::load(dirname(__FILE__) . '/testdata/test.json')->insert();
$f      = $obj->fixtures();

// 後始末
$obj->delete()->after();
// Db_Fixture::delete()->after(); とも書ける

まず load メソッドで 設定ファイルを読み込み、PDO を作成します。
第二引数に 設定ファイルのパスを設定する事も可能です。


insert メソッドで Fixture ファイルのデータを全て挿入します。
$obj->fixtures(); で挿入したデータを全て取得できます。
実際のテストコードとかで使用する場合は、取得したデータとこの $f に格納されているデータと比較する事になると思います。


delete メソッドは挿入したデータを消し、 after メソッドは Db_Fixture の属性を null にします。
PDO のリソースの解放とかをします。

その他

このライブラリの公開場所は openpear を使用させて頂いています。いつもありがとうございます。
http://openpear.org/package/Db_Fixture
テストコードは lime で記述しています。
動かし方は 上記の URL 参照で。


不具合とかがあったら、お知らせ頂けると嬉しいです。

22:05 追記

fixture() というメソッド名を fixtures() と複数形に変えた。
それにともない属性も $_fixture から $_fixtures に変更。


テストコードがあるおかげで簡単に変更できる。素晴らしい。

22:15 追記

0.1.1 でパッケージとしてリリースした。