ユニットテスト
Yii のテストフレームワークは PHPUnit の上に構築されていますので、PHPUnitのドキュメント を通読して、まずは、ユニットテストの書き方に関する基本的な理解を得ることをお奨めします。 以下に、Yii におけるユニットテストの書き方に関する基本的な原則を要約します。
ユニットテストは CTestCase または CDbTestCase を継承した
XyzTest
というクラスの形で書かれます。 ここでXyz
はテストされるクラスを表します。 例えば、Post
クラスをテストするためには、対応するユニットテストの名前をPostTest
とする、というのが規約です。 基本クラスの CTestCase は汎用のユニットテストのためのものであり、一方、 CDbTestCase は アクティブレコード モデルをテストするのに適しています。 二つのクラスは、共に、PHPUnit_Framework_TestCase
を親クラスとして持っており、このクラスから継承した全てのメソッドを使用することが出来ます。ユニットテストのクラスは
XyzTest.php
と名付けられた PHP ファイルに保存されます。 規約によって、ユニットテストのファイルはディレクトリprotected/tests/unit
の下に保存します。テストクラスは主として
testAbc
と名付けられた一連のテストメソッドを含みます。 ここでAbc
は、多くの場合、テストされるクラスのメソッド名です。テストメソッドは通常、一続きのアサーション文 (
assertTrue
やassertEquals
) を含みます。 これらのアサーション文がターゲットクラスの振る舞いの妥当性を検証するチェックポイントとして働きます。
以下においては、主として、アクティブレコード モデルクラスのためのユニットテストを書く方法を説明します。 テストのクラスは CDbTestCase を継承したものにします。 というのは、CDbTestCase は前の章で紹介した、データベースフィクスチャのサポートを提供するからです。
ブログデモ の中の Comment
モデルクラスをテストしたいと仮定しましょう。
最初に CommentTest
という名前のクラスを作成して、protected/tests/unit/CommentTest.php
として保存します。
class CommentTest extends CDbTestCase { public $fixtures=array( 'posts'=>'Post', 'comments'=>'Comment', ); ...... }
このクラスの中で、fixtures
というメンバ変数を配列として定義し、このテストでどのフィクスチャが使用されるかを指定します。
配列は、フィクスチャの名前に対するモデルクラス名またはフィクスチャテーブル名 (例えば、posts
というフィクスチャ名に対する Post
というモデルクラス) という対応関係を表します。
フィクスチャテーブル名に対応付けるときは、テーブル名の前にコロンを付ける (例えば :Post
) 必要があることに注意して下さい。
そして、モデルクラス名を使う場合は、モデルに対応するテーブルがフィクスチャテーブルであると見なされます。
前に述べたように、フィクスチャテーブルはテストメソッドが実行されるたびに、毎回、一定の既知の状態にリセットされます。
フィクスチャ名を使うと、テストメソッドの中で簡単にフィクスチャデータにアクセスすることが出来ます。 下記のコードがフィクスチャ名の典型的な使用例です。
// 'Comment' フィクスチャテーブルの全ての行を返す $comments = $this->comments; // `Post` フィクスチャテーブルの 'sample1' というエイリアスの行を返す $post = $this->posts['sample1']; // 'sample1' フィクスチャデータ行を表す AR インスタンスを返す $post = $this->posts('sample1');
注意: テーブル名を使ってフィクスチャを宣言した場合 (例えば
'posts'=>':Post'
) は、上の三番目の用法はエラーになります。 なぜなら、テーブルがどんなモデルクラスに関連付けられているかについての情報が無いからです。
次に、Comment
モデルクラスの approve
メソッドをテストするための testApprove
メソッドを書きます。
コードは非常に単純です。
最初に保留状態のコメントをインサートします。
次にこのコメントをデータベースから参照して、保留の状態にあることを確認します。最後に approve
メソッドを呼んで、期待通りに状態が変化していることを確認します。
public function testApprove() { // 保留状態のコメントを挿入する $comment=new Comment; $comment->setAttributes(array( 'content'=>'comment 1', 'status'=>Comment::STATUS_PENDING, 'createTime'=>time(), 'author'=>'me', 'email'=>'me@example.com', 'postId'=>$this->posts['sample1']['id'], ),false); $this->assertTrue($comment->save(false)); // コメントが保留状態であることを確認する $comment=Comment::model()->findByPk($comment->id); $this->assertTrue($comment instanceof Comment); $this->assertEquals(Comment::STATUS_PENDING,$comment->status); // approve() を呼んで、コメントが承認状態になったことを確認する $comment->approve(); $this->assertEquals(Comment::STATUS_APPROVED,$comment->status); $comment=Comment::model()->findByPk($comment->id); $this->assertEquals(Comment::STATUS_APPROVED,$comment->status); }