githubのプライベートレポジトリでも利用できるCIサービスwerckerでPHPUnitのテスト実行環境を作成してみました。
Ruby on Rails + RSpecの例はよく目にしますが、PHPUnit(&DBUnit)の構築例があまり無かったので、実際に運用しているwercker.ymlと、その簡単な解説を共有します。
wercker.yml成果物
box: wercker/php
services:
- wercker/mysql
build:
steps:
- script:
name: Activate PHP 5.3
code: phpenv global 5.3
- script:
name: install ansible
code: |-
git clone git://github.com/ansible/ansible.git
cd ansible
git checkout v1.7.1
sudo make install
type ansible || { echo "ansible not found"; exit 1; }
- script:
name: ansible provisioning
code: sudo ansible-playbook -i ci/wercker/wercker_hosts ci/wercker/wercker.yml -c local
- script:
name: setup test db
code: mysql -h$WERCKER_MYSQL_HOST -P$WERCKER_MYSQL_PORT -u$WERCKER_MYSQL_USERNAME -p$WERCKER_MYSQL_PASSWORD $WERCKER_MYSQL_DATABASE < ci/wercker/db.sql
- script:
name: fill mysql env.
code: |-
sudo sed -i -e "s/WERCKER_MYSQL_HOST/$WERCKER_MYSQL_HOST/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_PORT/$WERCKER_MYSQL_PORT/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_USERNAME/$WERCKER_MYSQL_USERNAME/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_PASSWORD/$WERCKER_MYSQL_PASSWORD/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_DATABASE/$WERCKER_MYSQL_DATABASE/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
- script:
name: echo PHP information
code: |-
php -v
php -i
- script:
name: PHPUnit integration tests
code: |-
cd test/UnitTest
phpunit -c phpunit.xml lib/
after-steps:
- sherzberg/slack-notify:
subdomain: my_slack_subdomain
token: $SLACK_TOKEN
channel: my_slack_channel
解説
box: wercker/php
services:
- wercker/mysql
werckerオフィシャルBOXのwercker/php
を利用します。
このBOXには、PHP 5.5, 5.4, 5.3がphpenv
でインストールされており、環境にあったバージョンを選択できるようになっています。
また、今回はDBUnitのテストも行うため、servicesとしてwercker/mysql
を追加しています。
- script:
name: Activate PHP 5.3
code: phpenv global 5.3
PHPのバージョンを5.3に設定します。
プロダクション環境のバージョンに合わせて設定すると良いでしょう。
5.3は最新より一つ古い5.3.28がインストールされていました(2014.08.29時点)。
- script:
name: install ansible
code: |-
git clone git://github.com/ansible/ansible.git
cd ansible
git checkout v1.7.1
sudo make install
type ansible || { echo "ansible not found"; exit 1; }
pear/peclのライブラリインストールや、その他環境構築をansibleで行いたかったので、インストールしています。
- script:
name: ansible provisioning
code: sudo ansible-playbook -i ci/wercker/wercker_hosts ci/wercker/wercker.yml -c local
ansible-playbookで環境構築を行います。
- script:
name: setup test db
code: mysql -h$WERCKER_MYSQL_HOST -P$WERCKER_MYSQL_PORT -u$WERCKER_MYSQL_USERNAME -p$WERCKER_MYSQL_PASSWORD $WERCKER_MYSQL_DATABASE < ci/wercker/db.sql
DBのスキーマを流し込んでいます。
ここで使っているdb.sqlは、
$ mysqldump --single-transaction -d -q -hHOST -PPORT -uUSER -pPASSWD DBNAME > db.sql
のように-d(--no-data)を付けてプロダクションのDBから取得したスキーマオンリーのSQLファイルです。
WERCKER_MYSQL_*
の環境変数は、wercker/mysql
によって自動的に追加されるMySQL接続情報です。
werckerのEnvironment Variablesに自分で設定するものではありません。
値は毎回変わりますが、下記のような感じでした。
variable | value |
---|---|
WERCKER_MYSQL_HOST | 10.0.3.34 |
WERCKER_MYSQL_PORT | 3306 |
WERCKER_MYSQL_USER | wercker |
WERCKER_MYSQL_PASSWORD | wercker |
WERCKER_MYSQL_DATABASE | werckerdb1 |
- script:
name: fill mysql env.
code: |-
sudo sed -i -e "s/WERCKER_MYSQL_HOST/$WERCKER_MYSQL_HOST/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_PORT/$WERCKER_MYSQL_PORT/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_USERNAME/$WERCKER_MYSQL_USERNAME/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_PASSWORD/$WERCKER_MYSQL_PASSWORD/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
sudo sed -i -e "s/WERCKER_MYSQL_DATABASE/$WERCKER_MYSQL_DATABASE/g" $WERCKER_ROOT/test/UnitTest/phpunit.xml
PHPUnitで使うconfigファイル中のMySQL接続情報を、WERCKER_MYSQL_*
の値に書き換えています。
- script:
name: echo PHP information
code: |-
php -v
php -i
テスト前に一応PHPの設定情報をログに残しておきます。
- script:
name: PHPUnit integration tests
code: |-
cd test/UnitTest
phpunit -c phpunit.xml lib/
PHPUnit実行部です。
環境によってパスなどは書き換えてください。
after-steps:
- sherzberg/slack-notify:
subdomain: my_slack_subdomain
token: $SLACK_TOKEN
channel: "#my_slack_channel"
結果をslackに差し込むために、テスト後の処理を追加しています。
$SLACK_TOKEN
のような情報は、レポジトリに含めずにwerckerのEnvironment Variablesに設定しておくのが良いでしょう。
デプロイは別手順にしているため、werckerでは以上のテスト実行のみを行っています。
さいごに
werckerはβ版ということもあってか、たまにgithubに結果が返らない(wercker上ではテスト成功となっているが、github上ではPendingのまま)ようなこともありますが、手軽さと、無料でプライベートレポジトリが利用できるのは大きな魅力です。
正式サービスイン時にどういう料金体制になるかはまだ分かりませんが、これからCIを導入する方は、選択肢の一つとして検討しても良いのではないでしょうか。
今後はAndroidアプリのビルド+テスト+DeployGateでの配布なんかをやってみようと思っています。