Tbpgr Blog

Recruiting Operations tbpgr(てぃーびー) のブログ

RSpec | rspec command | example option とRSpecPiccoloの組み合わせ

概要

example option とRSpecPiccoloの組み合わせ

詳細

example option とRSpecPiccoloの組み合わせについて。
RSpecPiccoloは私が自作したgemで、パラメタライズドテストに利用します。

https://rubygems.org/gems/rspec_piccolo
https://github.com/tbpgr/rspec_piccolo

形式的にはRSpecの本来の記述方法からずれているのですが、
記述量が最低限で済み、楽なのでよく使っています。
プロダクトコードのひな形も生成するので、TDDやBDDの最初のRED・GREEN・リファクタリング
ループである、ファイル・クラス・メソッド名すら存在しない状態からのスタート、
というのをスキップすることができます。

RSpecPiccoloでは1つのcontextの中でテストのパラメータを配列+ハッシュの形式で保持します。
配列をループしながらケース数分の it を定義します。

手順

下記の手順でテスト実行までしてみます。
1. rspecの初期化
2. RSpecPiccoloでプロダクトコードとテストコードのひな形を生成
3. rspecで全テストを実行してみる
4. テストケースを増やす(テストのフィルタが目的なので中身は適当。)
5. rspecのexample optionで一部のテストのみ実行してみる

1.と2. rspec piccoloでプロダクトコードとテストコードのひな形作成
# まずはrspecのディレクトリ作成
$ rspec --init

# Hogeクラスをファイル名hogeで作成し、hoge/hige/hageのインスタンスメソッドの
# テストコードとプロダクトコードを生成する。
$ piccolo e Hoge hoge hoge hige hage -p

# 生成ファイルの確認
$ tree
┣ lib
| ┗ hoge.rb
┗ spec
    ┣ hoge_spec.rb
    ┗ spec_helper.rb

RSpecPiccoloで生成されたプロダクトコードの確認

lib/hoge.rb

# encoding: utf-8


class Hoge
  def hoge
    # TODO: implement your code
  end

  def hige
    # TODO: implement your code
  end

  def hage
    # TODO: implement your code
  end
end

RSpecPiccoloで生成されたテストコードの確認

spec/hoge_rspec.rb

# encoding: utf-8
require "spec_helper"
require "hoge"

describe Hoge do

  context :hoge do
    cases = [
      {
        case_no: 1,
        case_title: "case_title",
        expected: "expected",
      },
    ]

    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 --
          # TODO: implement execute code
          # actual = hoge.hoge

          # -- then --
          # TODO: implement assertion code
          # expect(actual).to eq(c[:expected])
        ensure
          case_after c
        end
      end

      def case_before(c)
        # implement each case before
      end

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

  context :hige do
    cases = [
      {
        case_no: 1,
        case_title: "case_title",
        expected: "expected",
      },
    ]

    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 --
          # TODO: implement execute code
          # actual = hoge.hige

          # -- then --
          # TODO: implement assertion code
          # expect(actual).to eq(c[:expected])
        ensure
          case_after c
        end
      end

      def case_before(c)
        # implement each case before
      end

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

  context :hage do
    cases = [
      {
        case_no: 1,
        case_title: "case_title",
        expected: "expected",
      },
    ]

    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 --
          # TODO: implement execute code
          # actual = hoge.hage

          # -- then --
          # TODO: implement assertion code
          # expect(actual).to eq(c[:expected])
        ensure
          case_after c
        end
      end

      def case_before(c)
        # implement each case before
      end

      def case_after(c)
        # implement each case after
      end
    end
  end
end
サンプルコード1(hoge_spec.rb)
# encoding: utf-8
require "spec_helper"
require "hoge"

describe Hoge do
  it "hoge1 1" do
    # some spec
  end

  it "hoge1 2" do
    # some spec
  end

  it "hoge2" do
    # some spec
  end
end
サンプルコード2(hige_spec.rb)
# encoding: utf-8
require "spec_helper"
require "hige"

describe Hige do
  it "hige1 1" do
    # some spec
  end

  it "hige1 2" do
    # some spec
  end

  it "hige2" do
    # some spec
  end
end
実行例:hoge1 1だけを実行
$ rspec -e 'hoge1 1'
Run options: include {:full_description=>/hoge1\ 1/}
.

Finished in 0.001 seconds
1 example, 0 failures
実行例:hoge1 1, hoge1 2を実行
$ rspec -e 'hoge1'
Run options: include {:full_description=>/hoge1/}
..

Finished in 0.001 seconds
2 examples, 0 failures
実行例:describe Hoge以下のexampleを全て実行
$ rspec -e 'Hoge'
Run options: include {:full_description=>/Hoge/}
...

Finished in 0 seconds
3 examples, 0 failures
実行例:hoge1 1, hoge1 2, hige1 1,hige1 2を全て実行
rspec -e 'hoge1' -e 'hige1'
Run options: include {:full_description=>/(?-mix:hoge1)|(?-mix:hige1)/}
....

Finished in 0 seconds
4 examples, 0 failures
3. rspecで全テストを実行してみる
$ rspec -fs
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}

Hoge
  hoge
    |case_no=1|case_title=case_title
  hige
    |case_no=1|case_title=case_title
  hage
    |case_no=1|case_title=case_title

Finished in 0 seconds
3 examples, 0 failures
4. テストケースを増やす(テストのフィルタが目的なので中身は適当。)

hoge_spec.rbの各caseの配列の要素を3つに増やす

配列部変更前

cases = [
  {
    case_no: 1,
    case_title: "case_title",
    expected: "expected",
  },
]

配列部変更後
(下記をhoge, hige, hageの全メソッドのテストケースに反映。hogeの部分はメソッド名に合わせる)

cases = [
  {
    case_no: 1,
    case_title: "hoge case1",
    expected: "expected",
  },
  {
    case_no: 2,
    case_title: "hoge case2",
    expected: "expected",
  },
  {
    case_no: 3,
    case_title: "hoge case3",
    expected: "expected",
  },
]
5. rspecのexample optionで一部のテストのみ実行してみる

・まずは全件実行

$ rspec -fs
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}

Hoge
  hoge
    |case_no=1|case_title=hoge case1
    |case_no=2|case_title=hoge case2
    |case_no=3|case_title=hoge case3
  hige
    |case_no=1|case_title=hige case1
    |case_no=2|case_title=hige case2
    |case_no=3|case_title=hige case3
  hage
    |case_no=1|case_title=hage case1
    |case_no=2|case_title=hage case2
    |case_no=3|case_title=hage case3

Finished in 0.00101 seconds
9 examples, 0 failures

・各ケース1のみ実行

$ rspec -fs -e case_no=1
Run options: include {:full_description=>/case_no=1/}

Hoge
  hoge
    |case_no=1|case_title=hoge case1
  hige
    |case_no=1|case_title=hige case1
  hage
    |case_no=1|case_title=hage case1

Finished in 0.00101 seconds
3 examples, 0 failures

hogeのケース1のみ実行

$ rspec -fs -e 'hoge case1'
Run options: include {:full_description=>/hoge\ case1/}

Hoge
  hoge
    |case_no=1|case_title=hoge case1

Finished in 0 seconds
1 example, 0 failures