Tbpgr Blog

元エンジニア 人事 tbpgr(てぃーびー) のブログ

RSpec | RSpecのテストレポートをtsv形式で出力してみる

概要

RSpecのテストレポートをtsv形式で出力してみる

詳細

RSpecのテストレポートをtsv形式で出力してみる

仕様

メソッド、ケース番号、ケース名、成功・失敗をtsv形式で出力する。
tsvにしたのはExcelにそのままはれるから。

構成

│  .rspec
│  Gemfile
│
├─lib:プロダクトコード
│  └─hoge
│      └─hige
│              hoge.rb
│
├─rspec_report:レポート機能により作成される
│  └─hoge
│      └─hige
│              hoge_spec.tsv
│
└─spec:テストコード
    │  spec_helper.rb
    │
    └─hoge
        └─hige
                hoge_spec.rb

プロダクトコード

# encoding: utf-8

class Hoge
  def hoge
    "hoge"
  end
  def hige
    "hige"
  end
end

テストコード

※ひな形の生成はrspec_piccoloを使ってます。
生成コマンドは以下

piccolo execute Hoge hoge/hige/hoge hoge hige
# encoding: utf-8
require "spec_helper"
require "hoge/hige/hoge"

describe Hoge do
  REPORT = "rspec_report"
  DIRS = File.path(__FILE__).gsub(/^.*\/spec\//, '').gsub(File.basename(__FILE__), '')
  OUT_DIR = "./#{REPORT}/#{DIRS}"
  REPORT_NAME = report_name = File.basename(__FILE__, ".rb")
  REPORT_FILE = "#{OUT_DIR}#{REPORT_NAME}.tsv"

  mkspec_report = Proc.new do
    Dir.mkdir(REPORT) unless File.exists?(REPORT)
    FileUtils.mkdir_p(OUT_DIR) unless File.exists?(OUT_DIR)
    File.open(REPORT_FILE, "w") {|f|f.puts "method\tcase\ttitle\tsuccess\/failure"}
  end.call

  success = Proc.new {|c|File.open(REPORT_FILE, "a") {|f|f.puts "\tsuccess"}}
  failure = Proc.new {|c|File.open(REPORT_FILE, "a") {|f|f.puts "\tfailure"}}

  context :hoge do
    cases = [
      {
        case_no: 1,
        case_title: "valid",
        expected: "hoge",
        success_hook: success,
        failure_hook: failure
      },
      {
        case_no: 2,
        case_title: "invalid",
        expected: "hogea",
        success_hook: success,
        failure_hook: failure
      },
    ]

    cases.each do |c|
      it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
        begin
          case_before c

          # -- given --
          hoge = Hoge.new

          # -- when --
          actual = hoge.hoge

          # -- then --
          ret = expect(actual).to eq(c[:expected])
        ensure
          case_after c
          sf_hook = ret ? c[:success_hook] : c[:failure_hook]
          sf_hook.call(c)
        end
      end

      def case_before(c)
        # implement each case before
        File.open(REPORT_FILE, "a") {|f|f.print "hoge\t#{c[:case_no]}\t#{c[:case_title]}"}
      end

      def case_after(c)
        # implement each case after
      end
    end
  end

  context :hige do
    cases = [
      {
        case_no: 1,
        case_title: "valid",
        expected: "hige",
        success_hook: success,
        failure_hook: failure
      },
      {
        case_no: 2,
        case_title: "invalid",
        expected: "hogea",
        success_hook: success,
        failure_hook: failure
      },
    ]

    cases.each do |c|
      it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
        begin
          case_before c

          # -- given --
          hige = Hoge.new

          # -- when --
          actual = hige.hige

          # -- then --
          ret = expect(actual).to eq(c[:expected])
        ensure
          case_after c
          hook = ret ? c[:success_hook] : c[:failure_hook]
          hook.call(c)
        end
      end

      def case_before(c)
        # implement each case before
        File.open(REPORT_FILE, "a") {|f|f.print "hige\t#{c[:case_no]}\t#{c[:case_title]}"}
      end

      def case_after(c)
        # implement each case after
      end
    end
  end

end

実行結果

プロジェクトルート直下にreportableディレクトリと関連サブディレクトリが
作成されてレポート結果のtsvファイルが出力されます。

これで、テストを実行するたびに最終結果がケース単位でtsvに出力されます。
現場で指定されている納品フォーマットのExcelに反映するなり出来ます。

hoge_spec.tsv

method	case	title	success/failure
hoge	1	valid	success
hoge	2	invalid	failure
hige	1	valid	success
hige	2	invalid	failure