CircleCI + KnapsackProでRailsのテストを高速化させる

More than 1 year has passed since last update.


CircleCIのテスト並列実行


  • CircleCIは複数のコンテナを利用してテストを並列実行させることができる。

  • コンテナを増やすとお金がかかる。

  • コンテナを増やすだけテストを早く終わらせることができる。


問題点


  • コンテナに割り振ったテストの実行時間にばらつきがあると、最終的なテストの完了時間=最もテストに時間がかかってるコンテナとなってしまう。


解決策


  • テストファイル毎の実行時間を保存して、再度テストする際は前回の実行時間を元に各コンテナにテストファイルを配分する。


Knapsack Proとは


使い方

基本的には 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を設定する。
    project_setting.png


ハマった箇所


  • vcr.gemを利用している場合spec_helper.rbに次のコードを書くように指示されるが、私の環境ではうまく動かなかった。

WebMock.disable_net_connect!(:allow => 'api.knapsackpro.com') if defined?(WebMock)

こちらに書かれているようにRakefileの最後に書くことによってうまく動作した。


効果


before

29分37秒

before.png


after

22分50秒

after.png


まとめ

完璧ではないが、そこそこいい感じに実行時間が平均化される。

https://knapsackpro.com/dashboard で各テストの実行時間を見ることができるので遅いテストの発見に役立つ。