Phalcon PHPでPHPUnitを使ってテストコードを書く
こんにちは、株式会社ライオンハートの鵜飼です。
引き続きPhalcon PHPについて、今回はPhalcon上でのPHPUnitの書き方についてのメモです。
また、今回の記述はPhalcon Devtoolsでプロジェクトを作成している環境を想定しています。
(app/config/config.php
や、app/config/services.php
がある環境)
Phalcon上のPHPUnitの環境作り
テストコードを格納するディレクトリは、app
ディレクトリと同階層にtests
という名前で作成しました。
/app /public /tests
このような形になると思います。
phalcon/incuvatorをインストール
ユニットテスト用の公式抽象クラスが配布されていますので、インストールしておきます。
composer require phalcom/incubator
phpunit.xmlを作成
公式ドキュメントを参考に、./tests/phpunit.xml
を作成していきます。
<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="./Bootstrap.php" backupGlobals="false" backupStaticAttributes="false" verbose="true" colors="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" syntaxCheck="true"> <testsuite name="Phalcon - Testsuite"> <directory>./</directory> </testsuite> </phpunit>
ほぼそのままです、何となくのイメージで、bootstrapはBootstrap.php
にリネームしています。
ヘルパ関数を作成
コチラはあっているのかどうかは詳しくは不明ですが、通常稼働する環境になるべく近くなるように大分いじくっています。
<?php use Phalcon\DI; use Phalcon\Mvc\Router\Annotations as Router; ini_set('display_errors',1); error_reporting(E_ALL); define('APP_PATH', realpath('..')); // phalcon/incubator のために必要 include APP_PATH . "/vendor/autoload.php"; try { /** * Read the configuration */ $config = include APP_PATH . "/app/config/config.php"; /** * Read auto-loader */ include APP_PATH . "/app/config/loader.php"; // composerの依存関係をオートロードする $registerDirs = $loader->getDirs(); $registerDirs[] = __DIR__; $loader->registerDirs( $registerDirs ); $loader->register(); } catch (\Exception $e) { echo $e->getMessage(); }
なるべく設定ファイルは使い回すように、app/config/config.php
や、app/config/loader.php
を利用しています。
データベース周りも同じ設定になっちゃってるので、この辺りは要調整ですね…。
テストコードのベースクラスを作成
もう一度公式ドキュメントのコードを参考にさせていただき、ベースクラスを作成します。
大きな変更点は、
UnitTestCase
->FunctionalTestCase
に変更- $configを
app/config/config.php
から取得 - $diを
app/config/services.php
で生成
という感じです。
<?php use Phalcon\DI; use Phalcon\Test\FunctionalTestCase as PhalconTestCase; abstract class UnitTestCase extends PhalconTestCase { /** * @var \Voice\Cache */ protected $_cache; /** * @var \Phalcon\Config */ protected $_config; /** * @var bool */ private $_loaded = false; public function setUp(Phalcon\DiInterface $di = NULL, Phalcon\Config $config = NULL) { /** * Read services */ $config = include APP_PATH . "/app/config/config.php"; include APP_PATH . "/app/config/services.php"; // ここで必要なDIコンポーネントを取得する。config があるなら、それを parent に渡すことを忘れずに parent::setUp($di, $config); $this->_loaded = true; } /** * Check if the test case is setup properly * * @throws \PHPUnit_Framework_IncompleteTestError; */ public function __destruct() { if (!$this->_loaded) { throw new \PHPUnit_Framework_IncompleteTestError('Please run parent::setUp().'); } } }
これでPHPUnitを利用する環境が整いました。
テストコードの記述
試しにトップページ(app/controllers/indexController.php
)にアクセスした場合のテストコードを書いてみます。
tests/IndexTest.php
という名前で下記のように記述しました。
<?php class IndexTest extends \UnitTestCase { public function testIndexAction() { $this->dispatch( '/' ); $this->assertController( 'index' ); $this->assertAction( 'index' ); $this->assertResponseCode( 200 ); } }
実行してテスト出来ているか確認します。
$ phpunit PHPUnit 4.8.5 by Sebastian Bergmann and contributors. Runtime: PHP 5.6.12 Configuration: /path/to/tests/phpunit.xml . Time: 523 ms, Memory: 12.50Mb OK (1 test, 3 assertions)
assertResponseCodeについてのメモ
今のところ原因は不明ですが、Controller側でsetStatusCode
で指定をしておかないと、assertResponseCode
で空文字が返ってきてしまいます。
$ phpunit PHPUnit 4.8.5 by Sebastian Bergmann and contributors. Runtime: PHP 5.6.12 Configuration: /path/to/tests/phpunit.xml F Time: 524 ms, Memory: 12.50Mb There was 1 failure: 1) Test\IndexTest::testIndexAction Failed asserting response code is "200", actual response status is "" /path/to/vendor/phalcon/incubator/Library/Phalcon/Test/FunctionalTestCase.php:180 /path/to/tests/IndexTest.php:15 FAILURES! Tests: 1, Assertions: 2, Failures: 1.
上の例で、エラーが出ないようにする時は、下記のように記述を追加しています。
<?php class IndexController extends ControllerBase { public function indexAction() { $this->response->setStatusCode( 200 ); } }
毎回書くのはしんどいので、エラーの時だけ書きたいのですが、全部書かないと行けないものなんですかね?
おまけ:PHPUnitのインストール
PHPUnitのインストールもかなり簡単になり、下記のコマンドを叩くだけで良くなりました。楽ちんです。
$ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ sudo mv phpunit.phar /usr/local/bin/phpunit $ phpunit --version PHPUnit 4.8.5 by Sebastian Bergmann and contributors.