Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

RSpec | パラメータ化テストのDSL化

概要

パラメータ化テストのDSL

詳細

下記記事のRSpecでパラメータ化テストをDSL化します。
RSpec | パラメータ化テスト
http://d.hatena.ne.jp/tbpg/20130715/1373901728

仕様

下記のような記載でテストケースのパラメータ群を記載できます。
スペース部分は左右サプレスします。

cases <<-_
  |value   |expected            |
  |"value" |"expected_value"    |
_

上記を定義すると以降のテスト内で@cases変数に内容がArray+Hashの形式で
保存されます。

実装としては、ヒアドキュメントをテキストとして取得して
パイプ区切りで値を切り出した上で、instance_evalしながら
Array+Hashに保存しました。
ダサい方法だと思いますが、お手軽です。

Moduleで実装したのでextendsすると利用可能になります。

実装コード

# encoding: utf-8
module ParameterizedTable
  def cases(case_table)
    @cases = []
    keys = get_keys(case_table.split("\n").first)
    case_table.split("\n")[1..-1].each_with_index do |line, line_index|
      words = get_values(keys, line)
      words[:case_no] = line_index + 1
      @cases << words
    end
  end

  private
  def get_keys(keys_line)
    keys_line.strip.split("|")[1..-1].map(&:strip)
  end

  private
  def get_values(keys, values_line)
    words = {}
    values_line.strip!.split("|")[1..-1].each_with_index do |word, word_index|
      words[keys[word_index].to_sym] = instance_eval(word.strip) 
    end
    words
  end
end

使用例

# encoding: utf-8
require_relative "../lib/string"
require_relative "parametarized_table"


describe String do 
  extend ParameterizedTable

  describe "kansuji?" do 
    cases <<-_
      |value|expected|
      |"一" |true    |
      |"二" |true    |
      |"三" |true    |
      |"四" |true    |
      |"五" |true    |
      |"六" |true    |
      |"七" |true    |
      |"八" |true    |
      |"九" |true    |
      |"十" |true    |
      |"1"  |false   |
      |""   |false   |
    _

    @cases.each do |c|
      it do 
        ret = c[:value].kansuji?
        expect(ret).to eq(c[:expected])
      end
    end
  end

  describe "kansuji_to_i" do 
    cases <<-_
      |value|expected|
      |"一" |1       |
      |"二" |2       |
      |"三" |3       |
      |"四" |4       |
      |"五" |5       |
      |"六" |6       |
      |"七" |7       |
      |"八" |8       |
      |"九" |9       |
      |"十" |10      |
      |"1"  |"1"     |
      |""   |""      |
    _

    @cases.each do |c|
      it "kansuji #{c[:value]} is number #{c[:expected]}" do 
        ret = c[:value].kansuji_to_i
        expect(ret).to eq(c[:expected])
      end
    end
  end

  describe "+" do 
    cases <<-_
      |value|addition|expected|
      |"一" |"一"    |2       |
      |"二" |"一"    |3       |
      |"三" |"一"    |4       |
      |"四" |"一"    |5       |
      |"五" |"一"    |6       |
      |"六" |"一"    |7       |
      |"七" |"一"    |8       |
      |"八" |"一"    |9       |
      |"九" |"一"    |10      |
      |"十" |"一"    |11      |
      |"1"  |"一"    |"1一"   |
      |""   |"一"    |"一"    |
    _

    @cases.each do |c|
      it "kansuji #{c[:value]} + kansuji #{c[:addition]} is number #{c[:expected]}" do 
        ret = c[:value] + c[:addition]
        expect(ret).to eq(c[:expected])
      end
    end
  end
end

結果

....................................

Finished in 0.007 seconds
36 examples, 0 failures