Blog

CakePHP2.0+Jenkinsで継続的インテグレーションを行う方法

 2012/05/25
このエントリーをはてなブックマークに追加

みなさんこんにちは。@ryuzeeです。

CakePHP2.0になってテスティングフレームワークがSimpleTestからPHPUnitに変わったことで、以前に比べると大分簡単にはなっていますが、まとまった情報が少ないので整理しておきます。

事前準備

JenkinsのインストールおよびCIサーバへのPHPのインストールは済ませておいてください。 CakePHP2.0でCIを行う場合は、以前のようにStagehand_TestRunnerを使ったりPhingを使う必要はありません(Phingは以前も使わない手もあった)が、PHPUnit、Xdebugのインストールは行なっておきます。 また今後利用するであろう、PMDやCPD等も導入しておくと良いでしょう。 なお、今回の作業はCentOS5.7上でPHP5.3.8を利用して行いました。

PHP関連のパッケージ導入

pecl install xdebug
pear channel-discover components.ez.no
pear channel-discover pear.phpunit.de
pear channel-discover pear.phpmd.org
pear channel-discover pear.symfony-project.com
pear channel-discover pear.symfony.com
pear channel-discover pecl.php.net
pear channel-discover pear.pdepend.org
pear channel-discover pear.netpirates.net
pear install --alldeps PhpDocumentor
pear install --alldeps phpunit/phpcpd
pear install --alldeps phpmd/PHP_PMD
pear install --alldeps phpunit/PHPUnit

Jenkinsのプラグイン導入

このあたりも定番です。 xUnit PluginおよびJenkins Clover PHP pluginを導入しておきます。 作業はJenkinsのプラグインマネージャから行なってもよいですし、コマンドラインからでも可能です。 必要に応じてcheckstyleやpmdプラグイン等をインストールしておいても良いでしょう。

CakePHP2.0でのアプローチ

基本

CakePHP2.0では標準でPHPUnitを利用するようになっており、それをラップするCakeシェルが用意されています。 例えばコマンドラインから以下のようにテストできます。

# コアライブラリを全部テストする
./lib/Cake/Console/cake test core AllTests

# app/Test/Case/Model/UserTest.php をテストする
./lib/Cake/Console/cake test app Model/User

また複数のテストをひとかたまりとしてTestSuiteを定義することもできます。 以下は、app/Test/Case/ 以下にあるModel、View、Controllerのテストをまとめて実行する例です。

app/Test/Case/AllTestsTest.php

class AllTests extends CakeTestSuite {
    public static function suite() {
        $suite = new CakeTestSuite('All tests');
        $suite->addTestDirectory(TESTS . 'Case' . DS . 'Controller');
        $suite->addTestDirectory(TESTS . 'Case' . DS . 'Model');
        $suite->addTestDirectory(TESTS . 'Case' . DS . 'View');
        return $suite;
    }
}

これを用意しておけば以下のようにアプリケーションロジックのみまとめてテストすることができます。

# アプリケーションを全部テストする
./lib/Cake/Console/cake test app AllTests

オプションの指定と様々な形式でのテスト結果ログの出力

上述のコマンドライン操作の際に、様々なオプションを追加することができます。

./lib/Cake/Console/cake test \
--log-junit=./reports/unittest.xml \
--coverage-html=./reports/coverage_html/ \
--coverage-clover=./reports/coverage.xml \
app AllTests

上記の例では、JUnit形式でテスト結果を出力、clover形式でカバレッジ情報を出力し、同じくカバレッジをhtmlで出力しています。 その他のオプションについては引数無しで以下のように実行すればOKです。 例えば特定のテストだけを実行したり、テストが失敗したところで実行を中止させたりできます。

./lib/Cake/Console/cake test

PHPUnit設定ファイルによるパラメータの設定

毎回手でオプションを入力するのは面倒ですが、PHPUnitではXMLファイルに設定を行って実行時に読み込ませることが可能になっています。 なお、カレントディレクトリにphpunit.xmlという名前でファイルを配置すると、無条件にファイルが読み込まれます。 それ以外のファイル名の場合は、実行時オプションで、–configuration を利用します。

XMLファイルは以下の通りです。

<phpunit>

<logging>
<log type="coverage-html" target="./reports/coverage_html/" title="My Project" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70"></log>
<log type="coverage-clover" target="./reports/coverage.xml"></log>
<log type="junit" target="./reports/unittest.xml" logIncompleteSkipped="false"></log>
</logging>

<filter>
  <blacklist>
    <directory suffix=".php">lib</directory>
    <directory suffix=".php">app/Test</directory>
    <directory suffix=".php">app/Vendor</directory>
  </blacklist>
</filter>

</phpunit>

簡単に説明しておくと、loggingセクションで、先程コマンドラインで指定したような内容の指定を行なっています。 またfilterでは、処理の対象外にするディレクトリを指定しており、libやapp/Testやapp/Vendor以下についてはテストやカバレッジ取得対象から除外しています。

Jenkins側での設定

(なお、既にプロジェクトが作成済でバージョン管理システムとの連携等はできている前提で説明します。)

プロジェクトの設定画面に移動し、「ビルド」の箇所で「ビルド手順の追加」をクリックし、中から「シェルの実行」を選択します。 シェルコマンドの入力欄には以下のように入力してください。

cd ${WORKSPACE} && ./lib/Cake/Console/cake test --configuration=${WORKSPACE}/phpunit.xml app AllTests

次に、ビルド後の処理について設定します。 テストの実行結果とカバレッジの取得のみ設定を行なっている例なので、その他のチェックを行う場合はこのサイトの他のページ等を参照してください。

  • 「Clover PHP カバレッジレポートを集計」にチェックを入れ、集計対象のXMLファイルをphpunitの設定ファイルと揃える
  • 「Clover HTMLレポートを公開する」にチェックを入れ、同様に公開対象のカバレッジ集計結果htmlのディレクトリを指定する
  • 「JUnitテスト結果の集計」にチェックを入れ、同様にテスト結果のXMLファイルをphpunitの設定ファイルと揃える

以上で完了です。 ページ下部の保存ボタンをクリックし設定を保存。その後ビルドを行なってみるとよいでしょう。

以下が実際のJenkinsの画面です。

それでは。

 2012/05/25
このエントリーをはてなブックマークに追加