CircleCIでparallelismを使ってRspecを並列実行すると、SimpleCovの結果がそれぞれのcoverageディレクトリにばらばらに出力されてしまいます。これを1つにまとめ、さらにCircleCI上で結果のHTMLが見えるようにしたい。
参考にしたページ:
- CircleCI で並列実行したRSpecのカバレッジを Coveralls に送る
- Merging test runs under different execution environments
- Storing Build Artifacts - CircleCI
複数のジョブのテスト結果を1つのディレクトリにコピー
SimpleCovの結果は、coverageディレクトリの下のJSONファイル .resultset.jsonに 出力されます。以下の「Copy coverage results」のように、Rspecの実行後にJSONファイルを /tmp/coverage/.resultset-番号.json へコピーします。
さらにpersist_to_workspaceを使うと、/tmp/coverage 下のファイルをジョブ間で共有できます。RSpecの実行が終わるたびに、.resultset-番号.json がこのディレクトリに溜まっていきます。
なお、/tmp/coverage というディレクトリ名はてきとうです。
test:
parallelism: 4
# 略
steps:
# 略
- run:
name: rspec
command: |
bundle exec rspec --format RspecJunitFormatter \
--out test_results/rspec.xml \
--format documentation \
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split)
- store_test_results:
path: test_results
- run:
name: Copy coverage results
command: |
mkdir /tmp/coverage
cp coverage/.resultset.json "/tmp/coverage/.resultset-${CIRCLE_NODE_INDEX}.json"
- persist_to_workspace:
root: /tmp/coverage
paths:
- .resultset-*.json
SimpleCovの結果をまとめるタスク
最近のSimpleCovには、複数のJSONから1つのHTMLを出力する機能ができましたので、これをそのまま使うrakeファイルを書きます。
namespace :coverage do
desc "Collates all result sets generated by the different test runners"
task :report do
require 'simplecov'
SimpleCov.collate Dir["/tmp/coverage/.resultset-*.json"], 'rails'
end
end
並列テストが全部終わったら結果をまとめる
CircleCIのworkflowsの設定を行い、testジョブが全部終わったらreportジョブを走らせるようにします(以下の workflows - build_and_test - jobs - report の部分)。
reportジョブではrakeタスクの coverage:report を動かします。このとき、attach_workspace で 複数のJSONファイルが置かれた /tmp/coverage が使えるようにしておきます。これで、coverage の下にSimpleCovのHTMLができあがります。
さらに、store_artifacts を使うと coverage ディレクトリがCircleCIのArtifactsで一定期間保管され、ブラウザーから閲覧できるようになります。
jobs:
build:
# 略
test:
# 略
report:
docker:
- image: cimg/ruby:2.6.6-node
steps:
- checkout
- ruby/install-deps:
bundler-version: 2.1.4
- attach_workspace:
at: /tmp/coverage
- run:
name: Collates all result sets
command: bundle exec rails coverage:report
- store_artifacts:
path: coverage
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
- report:
requires:
- test
今後の課題
Rails 6のパラレルテストはRspecで使えるのか、CircleCI上ではどうすべきなのか、調査する。
私のCircleCI記事: