外部モジュールとの連携
サンプル・コード「DatabaseTest.php」の説明
サンプル・コード「DatabaseTest.php」の処理を説明します。
1つ目のgetConnection()メソッドでは、データベースとの接続方法を実装します。接続先データベースの情報を元に、PDOオブジェクトを生成しており、それをcreateDefaultDBConnection()メソッドの引数として与えます。2番目の引数'test'はデータベース名を指定しています。
--------------------------------------------------------------------------------
protected function getConnection()
{
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
return $this->createDefaultDBConnection($pdo, 'test');
}
--------------------------------------------------------------------------------
2つ目のgetDataSet()メソッドでは、データベースを初期化するためのデータ・セットの取得方法を実装します。ここでは、book-seed.xmlというXMLファイルからデータを取得します。
--------------------------------------------------------------------------------
protected function getDataSet()
{
return $this->createFlatXMLDataSet(dirname(__FILE__).'/book-seed.xml');
}
--------------------------------------------------------------------------------
XMLファイルを用いたデータの定義方法は2種類ありますが、今回はFlat XMLデータ・セット形式を使用します。まずは、テスト対象となるテーブルの内容を見てください。今回は、bookテーブルという書籍の情報を管理する入れ物を用意しました(図2)。
bookテーブルの定義に合わせて、テスト・データをFlat XMLデータセットで作成します(図3)。ルート要素は
getConnection()とgetData()は、テスト・ケースの初期化処理であるsetUp()メソッドから自動的に呼び出されます。従って、この2つのメソッドをオーバー・ライドすることで、データベースに接続し、XMLファイルで定義した内容でbookテーブルの内容が初期化されるようになります。後は、テーブルのデータを操作しながら、結果をアサーション・メソッドで確認するよう、テスト・メソッドを追加していく流れになります。
PHPUnit_Extensions_Database_TestCaseクラスでは、ひとかたまりのデータを一括して比較するためのアサーション・メソッドが追加されています。
(1)assertTablesEqual(a, b) - 2つのテーブルの内容が等しいことを確認
(2)assertDataSetsEqual(a, b) - 2つのデータセットが等しいことを確認
サンプル・コードでは、(2)のassertDataSetsEqual()メソッドを使って、用意したFlat XMLデータ・セットの内容でbookテーブルが正しく初期化されたかを確認しています。
--------------------------------------------------------------------------------
public function testInitDataSet()
{
$dataset = $this->getDataSet();
$this->assertDataSetsEqual(
$dataset,
$this->getConnection()->createDataSet(),
"データセットの初期化エラー"
);
}
--------------------------------------------------------------------------------
DROP TABLE IF EXISTS `book`; CREATE TABLE `book` ( `id` int not null COMMENT "レコードID", `title` varchar(80) not null COMMENT "作品名", `author` varchar(80) not null COMMENT "作者名", `year` year default null COMMENT "発表年", PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
図2-1: bookテーブル定義(book.sql) |
<?xml version="1.0" encoding="UTF-8" ?> <dataset> <book id="1" title="羅生門" author="芥川 龍之介" year="1915" /> <book id="2" title="雪国" author="川端 康成" year="1935" /> <book id="3" title="吾輩は猫である" author="夏目 漱石" year="1905" /> </dataset> |
図2-2: Flat XMLデータ・セット(book-seed.xml) |
$ mysql -uroot test -e "SELECT * FROM book" +----+----------------+------------------+------+ | id | title | author | year | +----+----------------+------------------+------+ | 1 | 羅生門 | 芥川 龍之介 | 1915 | | 2 | 雪国 | 川端 康成 | 1935 | | 3 | 吾輩は猫である | 夏目 漱石 | 1905 | +----+----------------+------------------+------+ |
図2-3: bookテーブルのレコード出力 |
データベース・テストの実行
テストを実行する前に、MySQLのtestデータベース(スキーマ)に、bookテーブルを作成してください。testスキーマは、MySQLをインストールするとデフォルトで作成されています。
※なお、実際にテストを実行する場合は、自己責任でお願い致します。また、事前にMySQLのデータをバックアップしておくことをお勧めします。
(1)テストケース、テーブル定義、データセットの3ファイルが存在することを確認します
--------------------------------------------------------------------------------
$ ls
DatabaseTest.php book.sql book.xml
--------------------------------------------------------------------------------
(2)bookテーブルをtestスキーマに作成します
--------------------------------------------------------------------------------
$ mysql -uroot test
--------------------------------------------------------------------------------
(3)phpunitコマンドでテストケースを実行します
--------------------------------------------------------------------------------
$ phpunit DatabaseTest.php
PHPUnit 3.4.12 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 6.50Mb
OK (1 test, 1 assertion)
--------------------------------------------------------------------------------
無事にテストが成功しました。bookテーブルのレコードを出力して、本当に初期化データが取り込まれているのか確認してみます(図2-3)。定義したデータ・セットと同じ内容のレコードが作成されています。
ちなみに、phpunitコマンドで再度テストを実行すると、既存のレコードはいったんすべて削除され、あらためてデータ・セットの内容にリセットされます。PHPUnit_Extensions_Database_TestCaseクラスを使うことのメリットはまさにそこで、プログラムの不具合によってデータの不整合が生じることを気にしなくて済むため、特に開発中のフェーズで役立ちます。
次のページでは、未実装のモジュールを補完してテストする方法について紹介しまず。