CakepPHPでユニットテスト 〜モデル偏〜

CakePHPにはユニットテストが用意されている。 『SimpleTest』を用いたもの。

CakePHP2からは、『PHPUnit』を用いたものに変わっている。 今回はCakePHP1.3で『SimpleTest』を用いたものを紹介する。

CakePHPの公式マニュアルに大体記載されているが、少し分かりにくい部分があるので動くコードとして紹介。

 ■事前準備

0.CakePHP1.3で動くアプリケーション設定が出来ていること 1.『SimpleTest』一式をダウンロードし、セット。 こちらのサイト(http://simpletest.sourceforge.net/)からダウンロードし、「app/venders/shells」に解凍して設置。 2.テスト画面用調整 「webroot/test.php」のapp・rootパスなどを、「webroot/index.php」と同様に調整 3.テスト画面表示 「http://xxxxx/test.php」にアクセス。Webrootの「test.php」にブラウザでアクセス出来るURL。 ※LocalPC環境なら、「http://localhost/xxxxx/test.php」など

以下のような画面が表示されたら準備OK。

■モデルのテスト

今回は、まずモデルのテストについてコードを記載しながら紹介。 コントローラなど他はまた別の記事で。

0.以下モデルをテストする app/models/entry.php 以下のisExistUser」と「getUsercount」のテストをする。

<?php
/**
* POST モデル
* 物理名 entry
*  
* @package models
* @author moritaro
* @version 1.0
*/
class Entry extends AppModel {
        /** モデル名 */
        var $name = 'Entry';
        /** プライマリーキー */
        var $primaryKey = 'user';
        /** デフォルト バリデーション */
        var $validate = array();

        var $validationSets = array(
                                   'add' => array(
                                                  "user" => array(
                                                                  "message" => "notEmpty error!!!",
                                                                  "rule" => "notEmpty",
                                                                  "last" => true,
                                                                 )
                                                 ),
                                   ); 
        /**
        * Entryテーブル内ユーザー存在チェック
        * @param string $user
        * @return bool
        */
        function _isExistUser( $user )
        {
           $options['conditions'] = array(
                                         'Entry.user' => $user,
                                         );
           $posts_data = $this->find("first",$options);
           if (!empty($posts_data)) return true;                     

           return false;
        }
        /**
        * Entryテーブル内ユーザーボタン押下数取得
        * @param string $user
        * @return int
        */
        function _getUsercount( $user )
        {
           $options['conditions'] = array(
                                         'Entry.user' => $user,
                                         );
           $options['fields'] = array(
                                     'count',
                                     );
           $data = $this->find("first",$options);
           return $data['Entry']['count'];
        }
}
?>

1.テスト用DB設定

app/config/database.php

var $test = array(   'driver' => 'mysql',   'persistent' => false,   'host' => 'localhost',   'login' => 'user',  'password' => 'xxxxxxx',  'database' => 'sample_users',   'prefix' => 'test_', );

2.テスト用データの準備

フィクスチャーを使い、配列データでDBのテーブル内容をテストデータとして擬似的に作る。 テーブルは以下のような感じ。

テーブル名:users
user varchar(255) primarykey
count int

app/tests/fixtures/entry_fixture.php

<?php
/*
* テストデータ
*
*/
class EntryFixture extends CakeTestFixture {
   var $name = 'Entry';
   var $import = 'Entry';

   //テスト用データ
   var $records = array(
                       array(
                            'user' => 'a',
                            'count'=> 1,
                            ),
                       array(
                            'user' => 'b',
                            'count'=> 5,
                            ),
                       );
}
?>

3.テストコード ようやくテストコード。 app/tests/cases/models/entry.test.php

<?php
/**
* Entry モデル TEST
* 物理名 entry
*  
* @package models
* @author moritaro
* @version 1.0
*/
class EntryTestCase extends CakeTestCase {
    var $fixtures = array('app.entry'); //フィクスチャ (テストデータ)

    function startTest() {
        $this->Entry =& ClassRegistry::init('Entry');
    }

    function endTest() {
        unset($this->Entry);
        ClassRegistry::flush();
    }
    /**
    * モデル内のfunctionテスト「_isExistEmail」
    */
    // testで始まるメソッドがテスト実行対象
    function test_isExistUser() {
        //Functionの呼び出し
        $result = $this->Entry->_isExistUser("a");
        //Functionの予想結果
        $expected = true;
        //「Functionの返り値と予想結果が同じ」であることがテスト成功条件
        $this->assertEqual($result, $expected);
    }

    /**
    * モデル内のfunctionテスト「_getUsercount」
    */
    function test_getUsercount() {
        //Functionの呼び出し
        $result = $this->Entry->_getUsercount("b");
        //Functionの予想結果
        $expected = 5;
        //「Functionの返り値と予想結果が同じ」であることがテスト成功条件
        $this->assertEqual($result, $expected);
    }
}
?>

「assertEqual」 で、予想した結果と、メソッドの実行結果が同じであるかをテスト。

4.テスト実行

4−1.「http://xxxxx/test.php」にアクセスし、さきほどの画面を表示し、赤枠部分の「Test Cases」をクリック。

4−2.以下の画面が表示されるので、先ほど作成したモデルのテストである「models/Entry」をクリック。

4−3.テスト結果表示 テストが成功したら、以下のようにグリーンのバーが表示されます。 このサンプルでは、2つのメソッドがcompleteした表示となってる。 もし失敗した場合、レッドのバーが表示されます。

テスト駆動開発(TDD)の場合、グリーンになるようにテストコードを修正していく。 このテストが「グリーン」であるかぎり、コードは正しく動いている。 コードに修正が入った場合は、常にテストを実行する。 そうすることで、正しいコードが維持される。

この記事ではモデルのテストを紹介したが、今度の記事ではコントローラを紹介しようと思う。

【参考サイト】

CakePHP1.3でテストコード(1) -モデルのテスト- CakePHPのテストに触れてみる。 CakePHPを使ったテスト駆動開発 公式マニュアル