Skip to content

Instantly share code, notes, and snippets.

@euglena1215
Created November 30, 2023 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save euglena1215/61f8e400b98e8a37d50232d007663a18 to your computer and use it in GitHub Desktop.
Save euglena1215/61f8e400b98e8a37d50232d007663a18 to your computer and use it in GitHub Desktop.
エンドポイントごとのテストカバレッジを計測するための rake タスク
# frozen_string_literal: true
require 'find'
namespace :endpoint_coverage do
def fetch_all_routes
Rails.application.routes.routes.map do |route|
# `gsub`を使って`(.:format)`を除外します。
path = route.path.spec.to_s.gsub('(.:format)', '')
{ verb: route.verb, path: }
end
end
def extract_request_specs
specs = []
# spec/requests ディレクトリを再帰的に探索
base_paths = ['spec/requests']
base_paths.each do |base_path|
Find.find(base_path) do |filepath|
next unless filepath =~ /_spec\.rb\z/
# ファイルを読み込み、HTTPメソッドとパスを含む行を探す
File.readlines(filepath).each_with_index do |line, index|
next unless line =~ /(GET|POST|PATCH|DELETE|PUT) ([^'"]*)/
method = Regexp.last_match(1)
path = Regexp.last_match(2)
line = index + 1
specs << { path:, verb: method, filepath: "#{filepath}:#{line}" }
end
end
end
specs
end
task collect: :environment do
details_flg = ENV['DETAILS'] || false
# 全ルーティングを取得
routes = fetch_all_routes
# テストされたルートのリストを取得
tested_routes = extract_request_specs
# カバレッジの計算
untested_routes = routes.reject do |route|
tested_routes.any? { |tested_route| tested_route[:path] == route[:path] && tested_route[:verb] == route[:verb] }
end
# 結果の出力
puts "テストされたルート数: #{tested_routes.count}"
if details_flg
puts 'テストされたルート:'
puts(tested_routes.map { |route| "#{route[:verb]} #{route[:path]} at #{route[:filepath]}" })
end
puts "テストされていないルート数: #{untested_routes.count}"
if details_flg
puts 'テストされていないルート:'
puts(untested_routes.map { |route| "#{route[:verb]} #{route[:path]}" })
end
puts "全ルート数: #{routes.count}"
puts "カバレッジ: #{(tested_routes.count.to_f / routes.count * 100).round(2)}%"
end
task collect_for_admin: :environment do
details_flg = ENV['DETAILS'] || false
# 全 /admin のルーティングを取得
routes = fetch_all_routes.select { |route| route[:path].start_with?('/admin/') }
# テストされた /admin ルートのリストを取得
tested_routes = extract_request_specs.select { |route| route[:path].start_with?('/admin/') }
# カバレッジの計算
untested_routes = routes.reject do |route|
tested_routes.any? { |tested_route| tested_route[:path] == route[:path] && tested_route[:verb] == route[:verb] }
end
# 結果の出力
puts "テストされたルート数: #{tested_routes.count}"
if details_flg
puts 'テストされたルート:'
puts(tested_routes.map { |route| "#{route[:verb]} #{route[:path]} at #{route[:filepath]}" })
end
puts "テストされていないルート数: #{untested_routes.count}"
if details_flg
puts 'テストされていないルート:'
puts(untested_routes.map { |route| "#{route[:verb]} #{route[:path]}" })
end
puts "全ルート数: #{routes.count}"
puts "カバレッジ: #{(tested_routes.count.to_f / routes.count * 100).round(2)}%"
end
end
root@084b7fc12fd0:/usr/src/app# bundle exec rake endpoint_coverage:collect
テストされたルート数: 123
テストされていないルート数: 123
全ルート数: 123
カバレッジ: 12.34%
root@084b7fc12fd0:/usr/src/app# bundle exec rake endpoint_coverage:collect_for_admin
テストされたルート数: 123
テストされていないルート数: 123
全ルート数: 123
カバレッジ: 12.34%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment