Help us understand the problem. What is going on with this article?

【Rails】SimpleCovを使ってCircleCIでカバレッジを見れるようにするまで

SimpleCov とは

Ruby用のコードカバレッジ解析ツールです。

環境

インストール

Gemfile
group :test do
  gem 'simplecov'
end

RSpec実行時に、SimpleCovの結果が出力されるようにする

spec/spec_helper.rbの一番初めに、以下のような設定を記述します。

spec/spec_helper.rb
require 'simplecov'

# minimum_coverage、minimum_coverage_by_file はオプショナルです。
# - カバレッジが90%未満の場合、non-zero exit する(CircleCI上の場合、ジョブが失敗する)。
SimpleCov.minimum_coverage 90
# or
# - カバレッジが80%未満のファイルがあった場合、non-zero exit する(同上)。
SimpleCov.minimum_coverage_by_file 80

SimpleCov.start do                                     # 最低限、この行のみ必要。ブロックの中はオプション。
  add_filter '/spec/'                                  # /spec/ が含まれるファイルは除外する。
  add_filter do |source_file|
    source_file.lines.count < 5                        # 行数が 5行未満のファイルは除外する。
  end

  enable_coverage :branch                              # https://github.com/colszowka/simplecov#branch-coverage-ruby--25

  add_group 'Models', 'app/models'                     # 以降の設定で、グルーピングして結果を出力することが出来るようになります。
  add_group 'Services', 'app/services'                 # この設定をした場合も、All Files も含まれます。
  add_group 'Controllers (api)', 'app/controllers/api' # ここに含まれないものは Ungrouped として別タブで表示されます。
  add_group 'Controllers', 'app/controllers'
  add_group 'Helpers', 'app/helpers'
end

出力ファイル

rspec実行時に、coverage/index.htmlにファイルが出力されます。
open coverage/index.htmlなどでブラウザで確認してください。

注意(SimpleCovのレポートに、特定のクラスが含まれていない場合)

例えば、app/models/foo.rbというファイルがあった時に、このファイルに含まれるコードに対応するテストがまったくないと、そもそもSimpleCovのチェック対象とならず、coverage/index.htmlにも含まれないということがありました。
この場合、以下のような空ファイルを作成すると、結果に含まれるようになりました。

# frozen_string_literal: true

require 'rails_helper'

describe Foo, type: :model do
  # NOTE: This `it` is added to prevent the following warning by rubocop, Empty example group detected.
  it do
    # do nothing
  end
end

.gitignoreでcoverage以下を無視する

echo "coverage" >> .gitignore

CircleCIでSimpleCovの結果を確認する

このCircleCIの設定で以下の箇所を参照してください。
この設定により、rspecのジョブ完了時に、CircleCI上の該当ジョブのARTIFACTSタブで、coverage/index.htmlが確認できるようになります。

      - store_artifacts:
          path: coverage

その他

SimpleCovの対象にしたくない行

以下のように、:nocov:で囲います。

# :nocov:
def skip_this_method
  never_reached
end
# :nocov:

ref: https://github.com/colszowka/simplecov#ignoringskipping-code

特定の条件(カバレッジが低い等)で、non-zero exitさせる

ref: https://github.com/colszowka/simplecov#customizing-exit-behaviour

特定条件下でのみSimpleCovを実行したい場合

十分速いので基本的に必要となることはほぼない想定ですが、以下に書かれている通り、環境変数で制御することになります。

ref: https://github.com/colszowka/simplecov#running-coverage-only-on-demand

piggydev
フリーランスで、開発(Node (NestJS), Go, Rails, React/TypeScript)やプロジェクトマネージメント業務を行っています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away