drone.io(OSS版)で並列テストを実行してビルド時間を削減する
プロダクトが成長してテストコードの規模が大きくなってくるとテスト実行時間も延びてきます。成長は嬉しいけど、ビルド時間が延びるのは嬉しくないです。そこでテストを並列で実行できるようにdrone.ioを設定してみます。
なお、CircleCI2.0での並列テストの方法は同僚が試してくれました。以下の記事を参考にしてください。
マトリックスビルド
drone.ioにはマトリックスビルドという機能があります。これを使うことで複数のworker(Dockerコンテナ)を並列で実行させられます。設定は簡単です。
.drone.yml
pipeline:
build:
image: hoge/piyo
commands:
- RAILS_ENV=test bundle exec rspec ${TESTFOLDER}
matrix:
TESTFOLDER:
- spec/models
- spec/requests
これだけで2つのworkerが立ち上がり、それぞれで spec/models
と spec/requests
のテストを実行してくれます。やったね🎉 でも実際これは上手くいきません。なぜなら最も実行時間のかかるリクエストテストが1つのworkerに集中してしまっているからです。片方はすぐ終わるのに、結局全体の実行時間はあまり改善されません(CircleCIなら勝手にランダムにしてくれるんだけどな…)。
テストコードファイルを分散する
というわけで、テストコードのファイルを分散するようにします。雑に書いたスクリプト例です。
require 'fileutils'
require 'pathname'
class RandomDistSpec
def initialize
FileUtils.rm_rf("matrix_specs")
@worker_num = 4
end
def copy_ruby_spec
specs = Dir.glob("spec/**/*_spec.rb").shuffle
copy specs
end
private
def copy specs
slice_num = (specs.size / @worker_num).ceil
1.upto(@worker_num) do |i|
FileUtils.mkdir_p("matrix_specs/#{i}") unless FileTest.exist?("matrix_specs/#{i}")
files = specs.slice!(0, slice_num)
files.each do |file|
dir = Pathname(file).dirname.to_s
FileUtils.mkdir_p "matrix_specs/#{i}/#{dir}"
FileUtils.cp file, "matrix_specs/#{i}/#{file}"
end
end
end
end
spec = RandomDistSpec.new
spec.copy_ruby_spec
こうすることで、 /matrix_specs/n
ディレクトリにランダムにファイルが配置されます。合わせて .drone.yml
も修正します。
matrix:
TESTFOLDER:
- matrix_specs/1
- matrix_specs/2
これでテスト実行時間が無事削減できました。
CIは非常に便利ですが、CIでのビルド時間が長いと改善サイクルが上手く回せません。待ち時間が発生し、集中力を取り戻すのにコストがかかります。なのでCIは積極的に改善をしていくべきところだなぁと思いました。
Author And Source
この問題について(drone.io(OSS版)で並列テストを実行してビルド時間を削減する), 我々は、より多くの情報をここで見つけました https://qiita.com/zaru/items/2bc075d68875911cb63e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .