CircleCIで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でコンビニエンスイメージを使っているため、他に都合良い言語がなかった。
先程用意したスクリプトを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"
これは実際に業務でトライしたことだったのだが、テスト間の実行順に依存関係があるらしく、並列化でのテスト実行を簡単に実現することができなかった...
まずは依存関係を何とかする必要がある...