Rails
RSpec
coverage
spec
rake_task

simplecovで生成されるhtmlレポートからcsvを作る開発用rake taskの作成

More than 1 year has passed since last update.

経緯

coverage率を追って、どれだけの変化があったか等を記録していくのに、htmlではやりづらさがかなりあった。

csvに出力したりする方法を探してみたものの、思うようなものが発見できなかったので自分で実装してみた。

コードは汚いし、本当ならgemのメソッドのどこかにhookして、htmlでなく、ちゃんとデータからcsvを作成できるようにすべきだが、時間がなかったので、このようなコーディングをした。

誰かもっといい方法を知っていたら教えて欲しい!!

使い方

1. $> bundle exec rake dev:make_csv_from_coverage_html:create

2. コマンド入力を要求されるので、生成元になるhtmlのpathを入力

3. 保存先と保存ファイル名をコマンド入力

4. DONE

ソースコード

make_csv.rb
namespace :dev do
  namespace :make_csv_from_coverage_html do
    desc "make csv from coverage html file"
    task :create => :environment do

      # 元になるhtmlファイルをpathで指定
      # コマンド入力で取ってこれるようにしてある
      print("Input coverage html file path : ")
      open_file_path = STDIN.gets
      open_file_path = open_file_path.chomp
      coverage_file = open("#{open_file_path}")

      header = []
      row_data = []
      coverage_file.each do |line|
        if line.include?("table class=\"file_list\"")
          while l = coverage_file.gets
            if l.include?('<th>')
              header << l.strip.delete('<th>').delete('</th>')
            elsif l.include?('</tr>')
              break
            end
          end
        end

        if line.include?('<tr>')
          row = []
          while l = coverage_file.gets
            if l.include?('<td')
              l = l.strip

              if l.include?('href')
                # file名
                match_str = l.match('title')
                post_str = match_str.post_match
                match_str2 = post_str.match("\">")
                post_str2 = match_str2.post_match
                match_str3 = post_str2.match('</a></td>')
                row << match_str3.pre_match
              elsif l.include?("\">")
                # coverage %
                match_str = l.match("\">")
                post_str = match_str.post_match
                row << post_str.delete('</td>')
              else
                # others
                row << l.strip.delete('<td>').delete('</td>')
              end
            end

            if l.include?('</tr>')
              break
            end
          end
          row_data << row
        end

        if line.include?('</table>')
          break
        end
      end

      csv_data = CSV.generate do |csv|
        csv << header
        row_data.each do |row|
          csv << row
        end
      end

      # 保存先もコマンド入力で自分で指定できるようにした
      print("\n Input coverage csv file path after saving\n For Example coverage/csv/coverage_#{Date.today}.csv \n")
      save_file_path = STDIN.gets
      save_file_path = save_file_path.chomp
      File.open("#{save_file_path}", "w") do |file|
        file.write(csv_data)
      end
    end
  end
end