PHPUnit+DbUnit
引き続きPHPUnitドキュメント読みつつ進めてみる
とにかくPHPUnit_Extensions_Database_TestCaseを使えるようにしないといけないのだけど、こいつ自体はDbUnitに入ってる模様なので、DbUnitを入れる
pear install phpunit/DbUnit
んでディレクトリ構造
├── fixture.yaml ├── fixture1.xml ├── fixture2.xml ├── phpunit.xml └── tests └── sample.php
でディレクトリ構造にあるようにデータベースにテストデータを注入するfixture自体が色々種類がある
- 通常のXMLファイル
- フラットなXMLファイル
- YAMLファイル
- CSVファイル
他にも色々あるけど、今回はフラットなXMLファイルとYAMLファイルの2つをやってみる
phpunit.xml
<?xml version="1.0" ?>
<phpunit>
<php>
<var name="DB_DSN" value="mysql:dbname=sample" />
<var name="DB_USER" value="user" />
<var name="DB_PASS" value="pass" />
</php>
<testsuites>
<testsuite>
<directory suffix=".php">tests</directory>
</testsuite>
</testsuites>
</phpunit>
な感じでデータベース接続に必要な情報をphpunit.xml側に設定する。これでスーパーグローバル変数から参照出来る模様
fixture1.xml
<?xml version="1.0" ?>
<dataset>
<sample id="1" name="hoge" created="2013-01-01 00:00:00" />
<sample id="2" name="fuga" created="2013-01-02 00:00:00" />
</dataset>
<dataset>内のノードはノード名がテーブル名、属性がカラム名とその値になるようなのでそのフォーマット方式に従って定義する
fixture2.xml
<?xml version="1.0" ?>
<dataset>
<item id="3" name="foobar" price="100" />
</dataset>
fixture1.xmlと同様なフラット方式なXMLファイル。PHPUnit_Extensions_Database_DataSet_CompositeDataSetを使う事でfixtureを複数使う事が出来る模様
fixture.yaml
sample:
- name: hoge
created: "2013-01-01 00:00:00"
- name: fuga
created: "2012-01-01 00:00:00"
あとは上記のをテストケース上で使うだけ
tests/sample.php
<?php
// 普通のXML FixtureはcreateXMLDataSet
// フラットなXML FixtureはcreateFlatXmlDataSet
// mysqldump --xmlな場合はcreateMySQLXMLDataSet
class SampleTestCase extends PHPUnit_Extensions_Database_TestCase {
private $db;
private function getDB() {
if (is_null($this->db)) {
global $DB_DSN, $DB_USER, $DB_PASS;
$this->db = new PDO($DB_DSN, $DB_USER, $DB_PASS);
}
return $this->db;
}
// PHPUnit_Extensions_Database_TestCaseで必要
public function getConnection() {
return $this->createDefaultDBConnection($this->getDB(), "sample");
}
// PHPUnit_Extensions_Database_TestCaseで必要
public function getDataSet() {
/* CompositeDataSetを使う場合
$ds1 = $this->createFlatXmlDataSet("fixture1.xml");
$ds2 = $this->createFlatXmlDataSet("fixture2.xml");
return new PHPUnit_Extensions_Database_DataSet_CompositeDataSet(
array($ds1, $ds2)
);
*/
return new PHPUnit_Extensions_Database_DataSet_YamlDataSet("fixture.yaml");
}
public function test1() {
$db = $this->getDB();
$st = $db->prepare("SELECT * FROM sample");
$st->execute();
$results = $st->fetchAll(PDO::FETCH_ASSOC);
$this->assertCount(2, $results);
}
public function test2() {
$this->assertThat(
$this->getConnection()->getRowCount("sample"),
$this->equalTo(2)
);
}
}
ってな感じかなと。個人的にはあくまでfixture的な扱いを使う前提だけで良いのではと思う所(モデルとかテストする名目であれば別にDbUnitな機能を使う必要性があるのかが微妙)