外部モジュールとの連携

2010年4月21日(水)
伊丹 久兼

サンプル・コード「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)。ルート要素はで、その中に、テーブル名と同じ要素を1レコードずつ記述します。

 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クラスを使うことのメリットはまさにそこで、プログラムの不具合によってデータの不整合が生じることを気にしなくて済むため、特に開発中のフェーズで役立ちます。

 次のページでは、未実装のモジュールを補完してテストする方法について紹介しまず。

PCIアイオス株式会社

テンアートニ(現サイオステクノロジー)、ゼンド・ジャパンなどを経て現在、PCIアイオスに勤務。これまでに組込み開発からWebシステム開発まで幅広く開発を経験。現在は、オープンソースソフトウェアを利用したシステムの開発、運用、パフォーマンスチューニングを担当。特にLAMP(Linux/Apache/MySQL/PHP)環境を得意とする。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています