CakePHP2でユニットテスト 〜route.php編〜

みなさんこんにちは。
今回はCakePHP2でユニットテストをする方法を書いていきます。
僕は最近やっとCakePHPを使い始めて1年経過しましたが、多少大きな開発になるとやはりテストを書いたほうが早く開発が出来ますね。

また、やはりなんといってもテストがあるととにかく安心する!←これ大事

開発を進めていくにあたって、安心というものは最高に重要ですね。
僕は普段忙しくても、routeのテスト、モデルのテストは必ず書くようにしています。
最低限ここらへんのテストが正常であれば動くので。

viewとcontrollerは変更が激しいのでなかなか書かないんですけどね。。。

さて、前置きはこれくらいにして、これから何回かにわけて

  • route.phpのテスト
  • Modelのテスト
  • Controllerのテスト
  • Viewのテスト

を書いていきたいと思います。

それでは今回はroute.phpのテストを書いていきます。

適当にroute.phpに記述しよう

まずはCakePHPをインストールしてください。

インストール直後のroute.phpには以下の記述があるだけだと思います。

route.php

Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));

これだけでも十分テストを書いていけるのですが、もう1つくらいパターンの違うものを書いておきましょう。
route.phpに以下のコードを追加してください。

Router::connect('/circle', array(
        'controller' => 'pages',
        'action' => 'circle',
        'tag' => 'circle'
    ));

これで準備は出来ました。次はこのroute.phpに対するテストを書いていきましょう。

記述したroute.phpに合わせてテストを書こう

現在route.phpには以下の3つのRouterが設定されていると思います。

route.php

Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/circle', array(
        'controller' => 'pages',
        'action' => 'circle',
        'tag' => 'circle'
    ));

これらのroute.phpに対してテストを書いていきます。
app/Test/Case以下に ‘AppRoutesTest.php’ファイルを作成しファイルに以下の内容を書き込んでください。

AppRoutesTest.php

App::uses('Router', 'Routing');

class AppRoutesTest extends CakeTestCase {

    public function setUp(){
        parent::setUp();
        require APP . 'Config' . DS . 'routes.php';
    }

    public function tearDown(){
        Router::reload();
        parent:tearDown();
    }

    // ここからテスト!!
    public function testTopPage(){
        $expects = array(
            'controller' => 'pages',
            'action' => 'display'
        );
        $url = Router::parse('/');
        $this->assertEqual($expects['controller'], $url['controller']);
        $this->assertEqual($expects['action'], $url['action']);
    }

    public function testPagesAll(){
        $expects = array(
            'controller' => 'pages',
            'action' => 'display',
            'pass' => array(1)
        );
        $url = Router::parse('/pages/1');
        $this->assertEqual($expects['controller'], $url['controller']);
        $this->assertEqual($expects['action'], $url['action']);
        $this->assertEqual($expects['pass'], $url['pass']);
    }

    public function testCirclePage(){
        $expects = array(
            'controller' => 'pages',
            'action' => 'circle',
            'tag' => 'circle'
        );
        $url = Router::parse('/circle');
        $this->assertEqual($expects['controller'], $url['controller']);
        $this->assertEqual($expects['action'], $url['action']);
        $this->assertEqual($expects['tag'], $url['tag']);
    }
}

これでテストを書くことが出来ました!
コードの中身の説明ですが・・・

setUp()はテストが行われる前に実行される関数、tearDown()はテストが完了したあとに実行される関数です。
またそれぞれのテストケースですが、まず最初に$expects変数の中に、正しくルーティングが設定してあれば返ってくるであろう配列を書いておきます。
そしてRouter::parse()でURLをパースします。パースすることによって、route.phpに書いてあるルーティングに従って、CakePHPがcontrollerやactionを割り当てます。
その結果が$urlに入っているので、あとはPHPUnitのassertEqual()で正しいかどうかを調べています。

3番目のテストケース「testCirclePage」のときのように、少し特殊なルーティングを行っている場合、以下のようにすればどのような値が$urlにわたっているか調べることが出来ます。

$url = Router::parse('/circle');
debug($url);

こうやって調べてテストを書くことによって、どんなルーティングにも対応出来ているテストケースを書くことが出来ます!

テストを動かそう

それでは最後にテストを動かしましょう。
インストールしたディレクトリの最後に「test.php」と打てばGUIでテストを実行出来るページが表示されます。
こんな感じで↓

AppRoutesをクリックし、全てがグリーンであればテストは全て成功しています!
こんな感じで↓

また、先ほどのRouter::parse()の中身を見る方法は、この画面の赤い枠で囲まれた部分をクリックするとdebug結果を見ることが出来ます
赤枠をクリック!

debug結果が表示される

これでroute.phpのテストはなんでも書けるはず!!

最後に

いかがでしたでしょうか。
route.phpに対するテストは、CakePHPのテストの中でも1番簡単なので、これをまずは理解しましょう。
もし何かわからないことがあれば、@DAI199までリプライください!

テストに関しては以下の本が1番詳しく書いてあると思いました。

安藤 祐介 岸田 健一郎 新原 雅司 市川 快 渡辺 一宏 鈴木 則夫
技術評論社
売り上げランキング: 17,808