notebook

都内でWEB系エンジニアやってます。

SimpleCov+RSpecをRails以外のプロジェクトで動かす

SimpleCov+RSpecをRails以外のプロジェクトで動かす

概要

Rails以外のプロジェクトでSimpleCovを使ってカバレッジを出力するメモ

SimpleCovをRailsプロジェクトに入れてカバレッジ把握みたいなことはやっていたので同じ流れで簡単にできるというイメージでやったらつまずいた

Gemのソースコードに対してカバレッジを取ろうと次のリポジトリで導入してみた(目的はCodecovを使いたい)

swfz/hatenablog_publisher: hatenablog publish with imagefile

問題

単純にSimpleCovを入れてREADME通りの設定をしてRSpec動かした

しかし、ファイルは読み取れたがすべてのcoverageが0%となるよう

f:id:swfz:20200714193549p:plain

モジュール読み込み順序

調べてみたら下記のようにrequireの順番にも意味があるというissueにたどり着いた

simplecov shows 0.0% · Issue #77 · colszowka/simplecov

github.com

コメントとしてはこのあたり

simplecov shows 0.0% · Issue #77 · colszowka/simplecov

今回はテスト対象のライブラリ群hanenablog_publisherを読み込む前にSimpleCovの設定をするようにした

すべてのファイルが0%になるという状態のみ対応する場合は次のようなdiffのみで対応できる

  • spec/spec_helper.rb
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 2804618..602ea91 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,11 +1,16 @@
 require "bundler/setup"
-require "hatenablog_publisher"

 require 'simplecov'
 SimpleCov.start

+require "hatenablog_publisher"

SimpleCov.startで設定をしたあとに計測対象のコードを読み込まないとダメらしい

他Rails以外のプロジェクトだと設定が必要そうな項目を挙げる

プロファイル

もろもろの設定ファイルをまとめたプリセットを指定できる

Railsのときはこのディレクトリが生成されるからこういう設定いるよねとかそういうの

ソース見るとわかりやすい

test_frameworksではテストライブラリ側で自動生成されるディレクトリのリストを対象から除外(add_filter)している

ということでtest_frameworksを指定

  • spec/spec_helper.rb
SimpleCov.start do
  load_profile 'test_frameworks'
end

Formatter

SimpleCovとは関係ないがそもそもCodecovを使いたかったので載せておく

CodecovのREADMEの内容だけだとローカルの実行時にもCodecovへレポートを送信するような動作になっているようでTokenを環境変数に入れていないとエラーが出力される

テスト自体は失敗判定にはならないが気持ち悪いのでformatter指定を分ける

SimpleCov.start do
  if ENV['CI']
    require 'codecov'
    formatter SimpleCov::Formatter::Codecov
  else
    formatter SimpleCov::Formatter::MultiFormatter.new([
      SimpleCov::Formatter::SimpleFormatter,
      SimpleCov::Formatter::HTMLFormatter
    ])
  end
end

設定

最終的に次のようなspec_helperになった

  • spec/spec_helper.rb
require "bundler/setup"

require 'simplecov'
SimpleCov.start do
  load_profile "test_frameworks"
  enable_coverage :branch

  if ENV['CI']
    require 'codecov'
    formatter SimpleCov::Formatter::Codecov
  else
    formatter SimpleCov::Formatter::MultiFormatter.new([
      SimpleCov::Formatter::SimpleFormatter,
      SimpleCov::Formatter::HTMLFormatter
    ])
  end
end

require "hatenablog_publisher"

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = ".rspec_status"

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end
end

f:id:swfz:20200714193602p:plain

無事カバレッジを取れた

おわり

Railsプロジェクトだと単純にbundle installしてSimpleCov.start 'rails'だけ追加すればOK!だったのであまりREADMEも読まずに入れていたけど勉強になりました

良い悪いは置いておいてRails周辺のよしなにやってくれる感はすごいなと感じますね