インストール
PHPUnitのインストールは以下のコマンドで行う。
# pear config-set auto_discover 1 # pear install pear.phpunit.de/PHPUnit
auto_discoverでインストールがうまくいかない場合は。
# pear channel-discover pear.phpunit.de # pear channel-discover pear.symfony.com
DBのテストを行うためには拡張をインストールする。
以下のコマンドでインストールする。
# pear install phpunit/DbUnit
基本クラスの準備
DBのテストをするためには、PHPUnit_Extensions_Database_TestCaseを継承したクラスを用意する。
また、getConnectionメソッドとgetDataSetメソッドを定義する必要がある。
<?php require_once "PHPUnit/Extensions/Database/TestCase.php"; class CommonDatabaseTest extends PHPUnit_Extensions_Database_TestCase { /** * @var PDOのインスタンス生成は、クリーンアップおよびフィクスチャ読み込みのときに一度だけ */ static public $pdo = null; /** * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection のインスタンス生成は、テストごとに一度だけ */ public $conn = null; /** * データベースに接続 */ public function getConnection() { if ( $this->conn === null ) { if ( self::$pdo == null ) { self::$pdo = new PDO($GLOBALS['DB_DSN'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']); self::$pdo->query('SET NAMES UTF8'); } $this->conn = $this->createDefaultDBConnection(self::$pdo, $GLOBALS['DB_DBNAME']); } return $this->conn; } /** * フィクスチャを読み込んで、データベースを初期化する * * @return PHPUnit_Extensions_Database_DataSet_CompositeDataSet */ public function getDataSet() { $compositeDs = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet(array()); $dir = dirname(__FILE__) . '/fixture'; $fh = opendir($dir); while ($file = readdir($fh)) { if ( preg_match('/^\./', $file) ) { continue; } if ( preg_match('/\.xml$/', $file) ) { $ds = $this->createMySQLXMLDataSet("$dir/$file"); $compositeDs->addDataSet($ds); } } return $compositeDs; } }
ここで$GLOBALでアクセスしている値を設定するために、以下の様なXMLファイルを作成する。
設定ファイル名は「phpunit.xml」とする。
<?xml version="1.0" encoding="UTF-8" ?> <phpunit> <php> <var name="DB_DSN" value="mysql:dbname=dbname;host=localhost" /> <var name="DB_USER" value="root" /> <var name="DB_PASSWD" value="" /> <var name="DB_DBNAME" value="hogehoge" /> </php> </phpunit>
この設定ファイルを読み込むためには、以下の様なコマンドで実行することになる。
$ phpunit -c tests/phpunit.xml tests/
フィクスチャファイルのフォーマットは色々とある。
phpMyAdminでデータを作ってmysqldumpで出力、とかしたいので、
MySQL XMLデータセット形式を使う。
mysqldumpのコマンドは以下の様な感じになる。
$ mysqldump --xml -t -u [username] --password=[password] [database] > /path/to/file.xml
このファイルを読み込むためには、createMySQLXMLDataSetメソッドを使うことになる。
基本クラスのgetDataSetメソッド内で使用している。
テスト
テストはCommonDatabaseTestクラスを継承して行う。
DBテーブル内のデータの比較は、期待値をXMLで設定することができる。
「expected.xml」とするファイルを用意する。
<?xml version="1.0"?> <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <database name="primarire_unittest"> <table_data name="user"> <row> <field name="first_name">名前</field> <field name="last_name">苗字</field> <field name="gender">男</filed> </row> </table_data> <table_data name="log"> <row> <field name="action">register</field> <field name="created_at">2012-10-01 00:00:00</field> </row> </table_data> </database> </mysqldump>
このXMLは以下のようにcreateMySQLXMLDataSetで読み込む。
$expectedTables = $this->createMySQLXMLDataSet('expected.xml');
PHPUnitの機能で、透過的にXMLのデータを取得することが出来る。
例えば、userテーブルのデータを取得する場合は以下のようにする。
$expectedUser = $expectedTables->getTable('user');
また、テストの結果、実際にDBに入っているuserテーブルのデータを取得する場合は以下のようにする。
$doneUser = $this->getConnection()->createQueryTable('user', 'SELECT first_name, last_name, gender FROM user');
期待値と実際の値をチェックする場合はassertTablesEqualメソッドを使用する。
$this->assertTablesEqual($expectedUser, $doneUser);
以上のことを踏まえて、ユーザー登録処理をテストするコードは以下の様な感じになる。
require_once "CommonDatabaseTest.php"; class RegisterUserTest extends CommonDatabaseTest { public function testRegisterUser() { $user = array( 'first_name' => '名前', 'last_name' => '苗字', 'gender' => '男', ); $model = new User(); $model->registerUser($user); $expectedTables = $this->createMySQLXMLDataSet('expected.xml'); $expectedUser = $expectedTables->getTable('user'); $doneUser = $this->getConnection()->createQueryTable('user', 'SELECT first_name, last_name, gender FROM user'); $this->assertTablesEqual($expectedUser, $doneUser); } }