CircleCIのテスト並列実行
- CircleCIは複数のコンテナを利用してテストを並列実行させることができる。
- コンテナを増やすとお金がかかる。
- コンテナを増やすだけテストを早く終わらせることができる。
問題点
- コンテナに割り振ったテストの実行時間にばらつきがあると、最終的なテストの完了時間=最もテストに時間がかかってるコンテナとなってしまう。
解決策
- テストファイル毎の実行時間を保存して、再度テストする際は前回の実行時間を元に各コンテナにテストファイルを配分する。
Knapsack Proとは
- https://knapsackpro.com
- 各種CIサービスに対応したテストを分割することだけに特化したサービス。
- CircleCIのドキュメントにさり気なく書かれている。
使い方
基本的には https://github.com/KnapsackPro/knapsack_pro-ruby にかかれている通り設定を行えばよい。
Gemfile
group :test, :development do
gem 'knapsack_pro'
end
bundle install
$ bundle install
Rakefileの最終行に追記
KnapsackPro.load_tasks if defined?(KnapsackPro)
修正方法の確認
$ bundle exec rake knapsack_pro:install
このコマンドで何かがインストールされるわけではない。質問に答えていくと修正すべきソースの箇所を教えてくれる。
rspecを利用している場合はspec_helper.rbに次のコードを書けばよい。
require 'knapsack_pro' #先頭
# 略
KnapsackPro::Adapters::RSpecAdapter.bind #最後あたり
circle.ymlの修正
次のように修正する。私の場合はTurnip
を利用しているので、環境変数KNAPSACK_PRO_TEST_FILE_PATTERN
でテストファイルのパターンを指定している。rspec
のみであれば環境変数の指定は不要。
test:
override:
- KNAPSACK_PRO_TEST_FILE_PATTERN="spec/**/*{_spec.rb,.feature}" bundle exec rake knapsack_pro:rspec:
parallel: true
TOKENの取得と登録
- https://knapsackpro.com からユーザー登録を行いTOKENを取得する。
- CircleCI -> Projectの設定 -> Environment VariablesにKNAPSACK_PRO_TEST_SUITE_TOKEN_RSPECというNameでTOKENを設定する。
ハマった箇所
- vcr.gemを利用している場合
spec_helper.rb
に次のコードを書くように指示されるが、私の環境ではうまく動かなかった。
WebMock.disable_net_connect!(:allow => 'api.knapsackpro.com') if defined?(WebMock)
こちらに書かれているようにRakefile
の最後に書くことによってうまく動作した。
効果
before
after
まとめ
完璧ではないが、そこそこいい感じに実行時間が平均化される。
https://knapsackpro.com/dashboard で各テストの実行時間を見ることができるので遅いテストの発見に役立つ。