CircleCIでphpunitの並列テストを行う

アプリケーション

概要

CircleCIでphpunitの並列テストを行うアプローチについてかく。

PHPUnitの設定ファイルを生成するスクリプトを用意する

#!/bin/sh

basePath="/foo/bar"
testFiles=$@

xmlFileStringData=""
for file in $testFiles; do
    xmlFileStringData="${xmlFileStringData}<file>${basePath}/${file}</file>\n"
done

testFileString="$xmlFileStringData"

template="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<phpunit colors=\"true\" stopOnFailure=\"false\" stopOnError=\"false\" failOnWarning=\"false\" stderr=\"true\" bootstrap=\"path/to/bootstrap\">
    <php>
     <ini name=\"memory_limit\" value=\"1G\"/>
     <ini name=\"realpath_cache_size\" value=\"1M\"/>
    </php>
    <testsuites>
        <testsuite name=\"Test Suite\">
            ${testFileString}
        </testsuite>
    </testsuites>
</phpunit>"

echo "$template" > "path/to/ci_phpunit.xml"

こんな感じのスクリプトを用意して、設定ファイルを自動生成する。

shellscriptを書いているのはテストの実行をコンテナで行っている都合上、CIのjobでコンビニエンスイメージを使っているため、他に都合良い言語がなかった。

CircleCIでコンテナ毎にテストを振り分け並列化させる

先程用意したスクリプトをgenerate_phpunit.shとして、次のようなスクリプトで並列化の準備ができる。

circleci tests glob "path/to/testdir/**/*.php" | circleci tests split | xargs sh +x generate_phpunit.sh

後はテスト実行時に生成した設定ファイルを指定すれば、複数コンテナでテストが実行され、並列化ができる。

path/to/phpunit -c path/to/ci_phpunit.xml

docker-composeでテストする場合の一例。

docker-compose -f docker/docker-compose.test.yml run test ash -c "path/to/phpunit -c path/to/ci_phpunit.xml"

所感

これは実際に業務でトライしたことだったのだが、テスト間の実行順に依存関係があるらしく、並列化でのテスト実行を簡単に実現することができなかった...

まずは依存関係を何とかする必要がある...

参考


関連書籍