5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CircleCIAdvent Calendar 2020

Day 12

CircleCIでテストを非同期っぽく行う

Last updated at Posted at 2020-12-11

はじめに

push時にCircleCIでテストを行っていますが、テストが終わるのは1秒でも速いほうがよいので以降の処理に依存関係がないテストをbackgroundモードで実行し、非同期っぽいテストにしました。

利用環境
CircleCI Enterprise version 2.0

並列で実行できるテスト

CircleCIでテストをするとき、このような流れでテストを行うことが多いのではないでしょうか。実際にはこれ以外にテスト用コンテナやDBコンテナなどを起動する処理が必要ですが、ここでは省略しています。

flow-small.png

よく考えてみるとLintとユニットテストは独立した関係なので、Lintをしながら平行にDBマイグレーションをしたっていいはずです。
flow-2.png

Backgroundオプションによる並列化

CircleCIの場合Lintのジョブとユニットテストのジョブを分離させて並列テストを行うことができますが、無料プランだと並列実行はできませんし、mediumインスタンス(標準のサイズ)は2vCPU割り当てられているので、1ジョブの中で並列化させてみたいところ。
もしかしたらversion 2.1ではうまいことできるのかもしれませんが、残念なことに利用しているCircleCIは未だに2.0です。

あいにくCircleCIにはジョブの中で処理を並列化させる機能はありません(たぶん)。しかしbackgroundオプションを利用すると、コマンドの終了を待たずに次のステップに進みます。本当は名前の通り常駐プロセスを起動させる用途に使うオプションですが、処理の並列化にも使うことができます。
Background commands

Lintを実行するためにはcomposer install, bundle installなどパッケージのインストールは完了している必要があります。しかしDBマイグレーションは不要です。一方ユニットテストは、Lintが終わっている必要はありませんが、パッケージインストールに加え、DBマイグレーションも完了している必要があります。つまりこのような順番で実行すれば良いことになります。
flow-background.png

config.ymlの修正

では実際にconfig.ymlを修正してみましょう。config.ymlからテストの部分を抜粋しました。

config.yml
      - run:
          name: Waiting for DB connection
          command: dockerize -wait tcp://cidb:3306 -timeout 120s
      - run: mkdir -p ~/reports/coverage
      - run: composer cs-check-report > ~/reports/cs-check-results.xml # ←ここをbackground処理にしたい
      - run: php artisan migrate --database=cidb --path=database/migrations/foobar --seed
      - run: ./vendor/bin/phpunit -c ./phpunit.ci.xml --coverage-html ~/reports/coverage tests/

backgroud処理に変更するにはrunコマンドのアトリビュートにbackgroudをつけてあげます。この例ではこんな感じになります。

config.yml
      - run:
          name: Waiting for DB connection
          command: dockerize -wait tcp://cidb:3306 -timeout 120s
      - run: mkdir -p ~/reports/coverage
      - run:
          command: composer cs-check-report > ~/reports/cs-check-results.xml
          background: true # ←バックグラウンド処理にした
      - run: php artisan migrate --database=cidb --path=database/migrations/foobar --seed
      - run: ./vendor/bin/phpunit -c ./phpunit.ci.xml --coverage-html ~/reports/coverage tests/

この設定を行うと、composer cs-check-reportが実行されると同時に次のphp artisan migrateが開始されます。
非常に分かりづらい画像で恐縮ですが、composer cs-check-reportが実行中(水色)のまま、php artisan migrateが完了(緑色)になっているのがおわかりいただけるかと思います。出力表示部の右上にExit code出力がないことでもわかるかと思います。
cci.png

注意点

backgroudの本来の使い方とは異なるので注意が必要です。コマンドの完了を待たずに次に進むため、テスト結果に依存する処理がある場合は利用できません。たとえばテスト結果をartifactとしてアップロードする処理などです。また成否に関わらず次のテストに進んでしまうため、どこかのテストで失敗したら、その場で打ち切りたいケースなどには向いていないでしょう。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?