ユニットテスト

Yii のテストフレームワークは PHPUnit の上に構築されていますので、PHPUnitのドキュメント を通読して、まずは、ユニットテストの書き方に関する基本的な理解を得ることをお奨めします。 以下に、Yii におけるユニットテストの書き方に関する基本的な原則を要約します。

  • ユニットテストは CTestCase または CDbTestCase を継承した XyzTest というクラスの形で書かれます。 ここで Xyz はテストされるクラスを表します。 例えば、Post クラスをテストするためには、対応するユニットテストの名前を PostTest とする、というのが規約です。 基本クラスの CTestCase は汎用のユニットテストのためのものであり、一方、 CDbTestCaseアクティブレコード モデルをテストするのに適しています。 二つのクラスは、共に、PHPUnit_Framework_TestCase を親クラスとして持っており、このクラスから継承した全てのメソッドを使用することが出来ます。

  • ユニットテストのクラスは XyzTest.php と名付けられた PHP ファイルに保存されます。 規約によって、ユニットテストのファイルはディレクトリ protected/tests/unit の下に保存します。

  • テストクラスは主として testAbc と名付けられた一連のテストメソッドを含みます。 ここで Abc は、多くの場合、テストされるクラスのメソッド名です。

  • テストメソッドは通常、一続きのアサーション文 (assertTrueassertEquals) を含みます。 これらのアサーション文がターゲットクラスの振る舞いの妥当性を検証するチェックポイントとして働きます。

以下においては、主として、アクティブレコード モデルクラスのためのユニットテストを書く方法を説明します。 テストのクラスは 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);
}
$Id$

Be the first person to leave a comment

Please to leave your comment.