simplecov の流し読みをしたのでまとめておきます。
simplecov
simplecov とはテストカバレッジを計測する gem で、計測結果をあらゆるフォーマットで出力してくれます。
Rails と親和性も高く簡単に導入することができます。
コードリーディング
simplecov を require すると lib/simplecov.rb の中で、lib/simplecov/defaults.rb が読み込まれ以下のコードでデフォルトの設定がされます。
# Default configuration SimpleCov.configure do formatter SimpleCov::Formatter::HTMLFormatter load_profile "bundler_filter" load_profile "hidden_filter" # Exclude files outside of SimpleCov.root load_profile "root_filter" end # Gotta stash this a-s-a-p, see the CommandGuesser class and i.e. #110 for further info SimpleCov::CommandGuesser.original_run_command = "#{$PROGRAM_NAME} #{ARGV.join(' ')}" at_exit do next if SimpleCov.external_at_exit? SimpleCov.at_exit_behavior end
formatter は HTML が選択され、除外ディレクトリなどの filter の設定も最低限されます。
filter の設定は lib/simplecov/profiles/ 以下に定義されています。
at_exit では計測終了時の処理が定義されています。
# Autoload config from ~/.simplecov if present require_relative "load_global_config" # Autoload config from .simplecov if present # Recurse upwards until we find .simplecov or reach the root directory config_path = Pathname.new(SimpleCov.root) loop do filename = config_path.join(".simplecov") if filename.exist? begin load filename rescue LoadError, StandardError warn "Warning: Error occurred while trying to load #{filename}. " \ "Error message: #{$!.message}" end break end config_path, = config_path.split break if config_path.root? end
.simplecov ファイルを再帰的に探索し、読み込みます。
実際に simplecov を使う場合 lib/simplecov.rb の SimpleCov.start が初めに呼ばれます。
rails で使う場合は profile がすでに定義されているので SimpleCov.start "rails" と指定します。
def start(profile = nil, &block) require "coverage" initial_setup(profile, &block) require_relative "./simplecov/process" if SimpleCov.enabled_for_subprocesses? @result = nil self.pid = Process.pid start_coverage_measurement end
initial_setup メソッドでは profile の 読み込み、block の処理が行われ self.running = true で計測状態が変更されます。
start_coverage_measurement メソッドでは Coverage.start が呼ばれ計測が開始します。
SimpleCov.result は以下です。
該当のプロセスのカバレッジ結果から rootパス以下以外の結果を除外、 load されていないファイルの結果を初期化し merge します。
同時に self.running = false で計測状態を変更しています。
def result return @result if result? # Collect our coverage result process_coverage_result if running # If we're using merging of results, store the current result # first (if there is one), then merge the results and return those if use_merging wait_for_other_processes SimpleCov::ResultMerger.store_result(@result) if result? @result = SimpleCov::ResultMerger.merged_result end @result ensure self.running = false end
lib/simplecov/result.rb の format! を呼ぶことで coverage の結果を出力します。
# Applies the configured SimpleCov.formatter on this result def format! SimpleCov.formatter.new.format(self) endt
先述の通り formatter の指定がなければ SimpleCov::Formatter::HTMLFormatter がデフォルトで設定されているので、SimpleCov::Formatter::HTMLFormatter.new.format(self) が呼び出されて、html ファイルが出力されます。
以上です。