秋ですね!
食欲の秋、読書の秋、スポーツの秋etc
西川的には遠征の秋です!
決して旅行ではございません!うっす!
話変わりますがコード書くじゃないですか?
レビュー必要じゃないですか?
レビュー手順書つくらないとじゃないですか?
作るじゃないですか?
やりたかったこと
- 「こういうデータ」を送ったら「こう返ってくる」ことを確認する
レビュー手順に書いてたこと
- 「こういうデータ」を用意するためのデータをこうやっていろいろ用意する
- その途中に必要なデータが足りなかったらこうやって用意する
- 用意するためのデータを使って「こういうデータ」をこうやって作成する
- 実コマンドを実行する
- たくさん出てくる結果の中から「こういうデータ」に沿うものを探す
- 「こう返ってくる」ことを確認する
手順のためのの手順のための手順のための手順・・・(ry
手順がゲシュタルト崩壊や!
そしてそんな手順書を持ってレビューをお願いしたら用意途中の手順中に動きがおかしいと報告されることも。
Why!? cook+biz developer!!!
ほんとに見なきゃいけないところはどこ!?
手順途中のバグは別issueでしょ!?
ぃみゎかんなぃ。。。。
もぅマヂ無理。ユニットテストかこ。。。
ということで今回はYii1.1のユニットテストで「こういうデータ」をFixtureとして作るお話です。
前置きがとてつもなく長かった、、、(ヽ´ω`)
CDbFixtureManager は、最初に参照されたときに、すべてのフィクスチャファイルを読んで、それに基づいて対応するテーブルをリセットします。 テーブルをリセットするために、全ての行を削除し、オートインクリメントの主キーのためのシーケンス値をリセットし、そして、フィクスチャファイルからテーブルにデータ行を挿入します。
開発用のデータベースの中身をリセットされるの困るのでテスト用データベースにしたいです。
そしてほしい「こういうデータ」がテストごとに変わるので全部同じ所に入れるとFixtureファイルがややこしくなるのでできれば分けたいです。
やりたいこと
・テスト用データベースを用意
・各テストによって必要なデータ状況が違うのでそれぞれで用意
テスト用データベースを用意する話
/protected/config/test.php
のDB接続情報をテスト用データベースに変更します。
Fixtureファイルを用意します。
1 2 3 4 5 6 7 8 9 10 11 |
<?php return [ 'job1' => [ 'ID' => 1, 'job_title' => '求人情報1', ], 'job2' => [ 'ID' => 2, 'job_title' => '求人情報2', ] ]; |
ユニットテストを作ります。
まずはとにかく読み込んでくれるかどうかの確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php class FixtureTest extends CDbTestCase { public $fixtures = [ 'job_tbl' => 'Job', ]; protected function setUp() { parent::setUp(); die(); } public function testRun() { } } |
途中で止めたらFixture読み込んでデータ作られた状態になるかな?って思って。
1 |
$ ../../vendor/bin/phpunit unit/FixtureTest |
ッターン!!!!!
モデルが読み込めないとお叱りのようです。
あ。namespaceかな?
変えてみましょう。
1 2 3 |
public $fixtures = [ 'job_tbl' => 'master_g\modules\job\models\Job', ]; |
1 |
$ ../../vendor/bin/phpunit unit/FixtureTest |
ッターン!!!!!
テーブルがない、、、?
1 2 3 4 5 6 7 8 9 |
public static function setUpBeforeClass() { $db = Yii::app()->getDb(); $db->createCommand("CREATE TABLE job_tbl ( ID INTEGER(18), job_title VARCHAR(255) );") ->execute(); } |
こんな感じで テスト開始前にテーブル作ってみたところ無事テストデータベースにFixtureが適応されることが判明。
「YiiのFixtureはテーブルがあることが前提で動く」
という知識を習得。
余談:テスト毎にテーブル構成を書いてしまうと管理に無理あるので事前に空テーブルを作って用意することにしました。
各テストによって必要なデータ状況が違うのでそれぞれで用意する話
無事テストデータベースで動くようになって書きたいテストケースも書き終わった頃。
とあるテストでは「掲載中の求人データ」だけが必要。
別のテストでは「非掲載の求人データ」だけが必要。
同じテーブルのデータなので1つのFixtureで全部書いてました。
Yiiおじさん「これテストによって必要なデータ違うから分けたいよね。」
「たしかに。」
Yiiおじさん「出来るか知らないけどね!」
「ぱーどぅん?」
仕方ない。調べましょう。
次に、フィクスチャのデータをディレクトリ protected/tests/fixtures の下に置きます。 このディレクトリは、アプリケーション構成の中で、 CDbFixtureManager::basePath を構成して、別のディレクトリにカスタマイズすることも出来ます。
あれ?これ 出来るんじゃない?
ということでsetUp内でCDbFixtureManager::basePathを変更。
1 2 3 4 5 6 7 8 9 |
protected function setUp() { $fixturePath = Yii::getPathOfAlias('application.tests.fixtures.' . get_class($this)); if (is_dir($fixturePath)) { $this->_basePathOld = $this->getFixtureManager()->basePath; $this->getFixtureManager()->basePath = $fixturePath; } parent::setUp(); } |
デフォルトディレクトリの中にテストクラス名のディレクトリを作成しそこにFixtureを起きます。
こんな感じ。
corporation_tblがそれぞれに置いてあります。
1つの企業のデータを使うテストと複数企業のデータを使うテストのためのFixtureです。
それぞれのファイルはこんな感じ。
覚えたこと
- YiiのFixtureはテーブルがあることが前提
- Fixtureの格納場所は変えられる
- Fixtureのリセットタイミングはテストメソッド実行時
- なのでテストが終わった後テストデータベースが空になってなくても気にしないでOK
- リセットするときAUTO_INCREMENTの値もしっかりリセットしてるからPKの値をFixtureで設定しなくても平気そう
- でもリレーションの都合があるからちゃんと設定したほうが安心
- Fixtureに書くcolumnはテーブルのcolumn分全てなくてもOK
とにかくやりたかったこと全て無事クリアしました。
(∩´∀`)∩ワーイ
現在、クックビズでは新しいメンバーを募集しております!
このブログを書いているのはクックビズ株式会社の開発チームです。私たちと働いてみたいと思った方はWantedlyから話を聞きにきて下さいヽ(=´▽`=)ノ著者プロフィール
-
頭がだいたい赤と黄緑のプリンになってる系ぺちぱー。
推しのメンバーカラーって大事でしょう!?
最近書いた記事
Engineering2017.11.21BacklogAPI Library for PHPを作りました
Engineering2016.09.20Yii1.1でFixtureを使ったユニットテストを作成する
Engineering2016.07.05Codeceptionの文字化け直してコントリビューターになったよ