travis-ciで環境を切り分けたテストをする方法

More than 1 year has passed since last update.

環境を切り分けたテストがしたい時がある。

具体例を出すと、PHPにはmemcachedのエクステンションとしてMemcacheMemcachedの2つがある。

PHPer以外には冗談みたいな話であるが、本当である。

そして、その2つの環境に対応したパッケージのテストをする場合、2つのエクステンションが個々に入った環境を作らなくてはならないので面倒くさい

面倒くさい事はciにお任せしたいと思ったのでtravis-ciで環境を切り分けたテスト方法を調べて実行してみた。


同名env

travis-ciはバージョンごとにテストを実行してくれるのはよく知られていると思うが、

同名の環境変数ごとにもテストを実行してくれる。

つまり

php:

- 5.6
- 7.0
- hhvm
- nightly
env:
- EXT=none
- EXT=memcache
- EXT=memcached

だと、バージョン(3つ)×同名環境変数(3つ)で9個のテストが実行される。

あとは、環境変数を使用して環境を作るだけ。

参考:Environment Variables


環境変数を使用した環境切り分け

シェルのifで環境変数を見て実行するコマンドを切り分ける

before_install:

- if [[ $EXT = memcache ]]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi
- if [[ $EXT = memcached ]]; then echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi

上記は$EXT


  • memcacheであれば、Memcacheのエクステンションを有効にする

  • memcachedであれば、Memcachedのエクステンションを有効にする

という処理を行っている

これで環境構築はできた。


テストしたくない環境を除外

PHP7はMemcacheエクステンションには対応していないのでMemcacheエクステンションを使用したテストでは実行時に

Error: Class 'Memcache' not found

と、エラーが出てしまう。

これはパッケージを作った側にはどうしようもないので、PHP7×Memcacheのテストは実行しないようにしたい。

こういう時はmatrixを使う。

matrix:

exclude:
- php: 7.0
env: EXT=memcache
- php: nightly
env: EXT=memcache

上記は


  • バージョンが7.0で$EXTがmemcacheのテストを除外する

  • バージョンがnightlyで$EXTがmemcacheのテストを除外する(nightlyも7.0なので)

という処理になる。

matrixのexcludeに除外したい組み合わせを指定するとその組み合わせのテストを実行しないようにしてくれる。

excludeとは逆にincludeの設定もあって、例えば5.6だけMemcacheとMemcachedのテストがしたい場合は

php:

- 5.6
- 7.0
- hhvm
- nightly
env:
- EXT=none
matrix:
include:
- php: 5.6
env: EXT=memcache
- php: 5.6
env: EXT=memcached

となる。

参考:Customizing the Build #Build Matrix


まとめ


  • 基本は同名envを設定してenvごとに環境設定を行う

  • 実行したくないテストはmatrixのexcludeで除外

PHP以外にも環境を変えたテストを行いたい事はあると思うので覚えておくと楽かも。


おまけ

この記事のタイトルとは直接関係無いが、

MemcacheとMemcachedに対応させたテストをtravis-ciで実行するときに重要なポイントがあったので記しておく。


phpunitのグループ機能

PHPはphpunitでテストを実行するのだが、

今回の場合、Memcache用とMemcached用のテストを用意して環境別に実行したかった。

なのでphpunitのグループ機能を活用することにした。

    /**

* @group memcache
*/

public function testMemcache()
{
// ...
}

/**
* @group memcached
*/

public function testMemcached()
{
// ...
}

上記のようにgroupアノテーションをつけて

$ vendor/bin/phpunit --group memcache

のように実行すればmemcacheグループであるtestMemcache()だけが実行される。

travis-ciで実行する場合はコマンドを環境変数によって切り分ける

script:

- if [[ $EXT = none ]]; then vendor/bin/phpunit --group none; fi
- if [[ $EXT = memcache ]]; then vendor/bin/phpunit --group memcache; fi
- if [[ $EXT = memcached ]]; then vendor/bin/phpunit --group memcached; fi

あるいは、グループ名と環境変数の中身が同じならば

script:

- vendor/bin/phpunit --group $EXT

でも良いかもしれない。


HHVMのMemcacheエクステンションとMemcachedエクステンション

HHVMの事はあまり詳しくないのだが、HHVMには最初からMemcacheエクステンションとMemcachedエクステンションが入っているようだった。

逆にHHVMで

before_install:

- if [[ $EXT = memcache ]]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi

とエクステンションを有効にしようとすると、

/home/travis/build.sh: line 45: /home/travis/.phpenv/versions/hhvm/etc/php.ini: No such file or directory

のようにphp.iniが無いとエラーが出る。

なので、HHVMではエクステンションの有効化をしないようにした。

before_install:

- if [[ $EXT = memcache && $TRAVIS_PHP_VERSION != hhvm ]]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi
- if [[ $EXT = memcached && $TRAVIS_PHP_VERSION != hhvm ]]; then echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi


この記事で使用したリポジトリ

178inaba/travis-php-memcached-test