header image

Ryuzeeについて

mixi Twitter Twitter

携帯対応

QRコード

RING

人気ブログランキング

新着記事

5月 25th, 2009 PHP 2 Comments

まだ色々試行錯誤中なんだけど、途中経過としてメモ。

cakephpでSimpleTestを使ったテスト自動化をしているんだけど、コントローラーのテストでは、メソッドにredirectが含まれていると、テストが途中で中断してしまう。(テスト自体がリダイレクトされてしまう)。

絵で説明すると、最初にSImpleTestにアクセスすると、以下のような画面が表示される。これは特に問題ない。

caketest12
んで、メソッドの中にredirectが含まれないやつのテスト結果。これも緑なのでOK。

caketest31
じゃあ、ということで、以下のメソッドについてテストを書く。

function login(){
    if ($this->Auth->user())
    {
        if (!empty($this->data))
        {
            $this->log("ログインしました", LOG_DEBUG);
            $this->User->updateLoginInfo($this->Auth->user('id'));
            $this->redirect($this->Auth->redirect());
        }
        else
        {
            $this->redirect(array('action' => 'index'));
        }
    }
    else
    {
        if (!empty($this->data))
        {
            $this->Session->setFlash($this->Auth->loginError);
        }
    }
}

もう、ふんだんにredirectしちゃってる。まぁloginだから普通なんだけど。
んで、テスト内容的には

  • ログイン完了してたら、「ようこそ××さん」があるはず
  • GETでアクセスしたら、ログイン画面があるはず
  • 誤ったPOSTデータが来たら、ログインエラーのメッセージがあるはず

とかそんな感じになるかと思うのだが、これ、そのままだとテスト出来ない。
例えば、ログインのテストコードは以下のように書いてみる。

$data = array(
    "User" => array(
        "username" => "foo",
        "password" => "bar",
    ),
);
$result = $this->testAction('/users/login', array(
    'data' => $data,
    'fixturize' => true,
    'method' => 'post',
    'return' => 'contents')
);

これは正常ログインするケースなのだが、正しい動作なら、/usrs/loginで正常に認証を完了すると、ログイン後トップページにリダイレクトされて、「ようこそ××さん」とかが出るはず。なので、戻り値の$resultを正規表現でごにょごにょすれば完成のように見えるんだけど、このテストを実行すると、下図のようになる。

caketest22

残念ながら、テスト対象クラスの中のredirect関数で、本当にredirectされちまった。。。

ということで、対応方法を色々考えたのだが、一番手っ取り早い方法を書いておく。それは

runkit(PHPの拡張)

を使う。runkitは

runkitは、PHPの定数や関数、クラス、メソッドを追加・変更・削除したり、独自のスーパーグローバル変数を定義したりできるPHPのエクステンションです。

http://www.phppro.jp/phptips/archives/vol50/1より)
ということで、今ある関数やクラスの挙動を外部から動的に変更できるすぐれものだ。

こいつを使って、例えばこうする。

function setUp() {
    $this->Commodity =& ClassRegistry::init('Commodity');
    $this->User =& ClassRegistry::init('User');
    $this->User->useDbConfig = "test_suite";

    //redirectメソッドを抹消
    runkit_method_redefine("UsersController" , "redirect"  , '$url, $status = null, $exit = true'  , "return true;" );
    $this->Users = new TestUsers();
    $this->Users->constructClasses();
}

これで、UsersControllerのredirectメソッドは単にtrueを返すように挙動が変更され、テストが途中で中断されることもなくなった。
あくまでテストコードなので、これで十分だと思うのだが、どうだろうか?
もっと良い方法があればコメントで教えてほしいなぁと。

“[cakephp]testActionでredirectするアクションをテストする方法”へ2件のコメントがあります。

  • cakephp_jp 2009/12/06

    [cakephp]testActionでredirectするアクションをテストする方法 | Ryuzee.com Cat… http://bit.ly/6iosht #cakephp

  • CakePHP 1.3で単体テスト | 1000g 2010/07/20

    [...] ※[cakephp]testActionでredirectするアクションをテストする方法 | Ryuzee.com を参考にPHP拡張のrunkitを使うのも検討しましたが、どう探してもこのライブラリをWindowsで動かす方法が見つかりませ [...]

コメントする

XHTML: 以下のタグが利用可能です: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback

 


ads

読まなきゃモグリ