somemo's diary

プログラマ、雑記、プログラミング関係はLinkから、数式はこっちでまとめていることが多い

【Zendframework】Controllerのテスト

クイックスタートのアプリが完成したので、Zend Framework: Documentation: Zend_Test_PHPUnit(日本語) - Zend Framework Manualを参考に、Zendframeworkでのテスト方法を実施していきます。

※前提として、PHPUnitがインストールされていること

テスト用のコントローラとテストコントローラの作成

まずZend_toolを使用してコントローラを作成します。

zf.bat create controller User

Userコントローラ、UserTestコントローラ、ビューにindex.phtmlが作成されていれば問題無しです。

setupメソッドの修正

setupメソッドは、テストする環境設定用のメソッドです。Zend_toolで作成した場合、下記のように記述されています。

public function setUp()
{
    $this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
    parent::setUp();
}

まず、APPLICATION_ENV定数を、テスト用に「testing」へ変更します。これでテスト用の設定(application.ini)が適用されます。

Web上で実行しない場合、apacheは関係ないので環境変数は適用されず、tests/bootstrap.phpに記載されているAPPLICATION_ENVが環境になります。

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

indexActionのテスト内容

下記が作成されたUserTestコントローラのtestIndexActionです。

public function testIndexAction()
{
    $params = array('action' => 'index', 'controller' => 'User', 'module' => 'default');
    $urlParams = $this->urlizeOptions($params);
    $url = $this->url($urlParams);
    $this->dispatch($url);
    
    // assertions
    $this->assertModule($urlParams['module']);
    $this->assertController($urlParams['controller']);
    $this->assertAction($urlParams['action']);
    $this->assertQueryContentContains(
        'div#view-content p',
        'View script for controller <b>' . $params['controller'] . '</b> and script/action name <b>' . $params['action'] . '</b>'
        );
}

$params変数に配列でmodule、controller、actionを指定しています。この変数をURLに変換し(たぶんルーティングとかやってるはず)、URLを渡してdispatchすることで、実際にアクセスしているようにします。

次からアサーションでテストを行います。各メソッドで次のテストを行っています。

  • Module
  • Controller
  • Action
  • ビュー(CSSセレクタでhtml要素を指定し、その内容をテストする)

テスト結果

まず、テスト対象はtests/phpunit.xmlに記載されている内容です。

<phpunit bootstrap="./bootstrap.php">
    <testsuite name="Application Test Suite">
        <directory>./application</directory>
    </testsuite>
    <testsuite name="Library Test Suite">
        <directory>./library</directory>
    </testsuite>
    
    <filter>
        <!-- If Zend Framework is inside your project's library, uncomment this filter -->
        <!-- 
        <whitelist>
            <directory suffix=".php">../../library/Zend</directory>
        </whitelist>
        -->
    </filter>
</phpunit>

これまで作成したテストコードは、tests/applicationに存在するのでテスト対象になっています。

今回作成したUserTestコントローラは、アクションとビュー共に修正していないのでグリーンです。

一方、クイックスタートで修正をGuestbookコントローラーは修正を行っているので、レッドになっています。

テスト結果は以下のとおりです。

C:\>phpunit -c \zend\tests\phpunit.xml
PHPUnit 3.5.15 by Sebastian Bergmann.

FF..

Time: 2 seconds, Memory: 14.25Mb

There were 2 failures:

1) GuestbookControllerTest::testIndexAction
Failed asserting last controller used <"error"> was "Guestbook"

C:\zend\library\Zend\Test\PHPUnit\ControllerTestCase.php:1000
C:\zend\tests\application\controllers\GuestbookControllerTest.php:21

2) GuestbookControllerTest::testSignAction
Failed asserting node denoted by div#view-content p CONTAINS content "View script for controller <b>Guestbook</b> and script/action name <b>sign</b>"

C:\zend\library\Zend\Test\PHPUnit\Constraint\DomQuery.php:263
C:\zend\library\Zend\Test\PHPUnit\ControllerTestCase.php:337
C:\zend\tests\application\controllers\GuestbookControllerTest.php:43

FAILURES!
Tests: 4, Assertions: 14, Failures: 2.

testSignActionでは、想定どおりのエラーが表示されています。

testIndexActionでは、コントローラーが違っているというエラーが表示されています。testSignActionの結果が影響しているように思います・・・。

まとめ

ここまでテストをしてきましたが、一般的なユニットテストというよりsymfonyでいう機能テストよりかなと思います。しかも、modelをZend_toolで作成しても、テストコードは作成されません。

今度はmodelのテストを試してみます。