Rspec入門。Rspecの構文解説。describe, context, it

 

Rspecを書こう!と決めたはよいもののRspecってRspec独自の構文で書く必要があるので普通にRubyを書くのはちょっと抵抗ありますよね。

ここは慣れるまでちょっと大変ではあるのですが、Rspecでテストコードがかけるようになるとコードもきれいになるし、コードの品質もあがりデプロイの自動化など作業の効率化にもつながるのでぜひとも身につけていきたいです。

それではRspecを書くにあたって必要そうな構文をひとつずつグループに分けて説明していきます。

 

describe,context,itの使い分け

Rspecファイルを開いたときにまず目に飛び込んでくるのがdescribeやcontext,itなどの見慣れない構文ですが、これはテストケースのグルーピングに使用します。

コード例

 

require 'rails_helper'

RSpec.describe Blog, type: :model do
  describe '#truncated_content' do
    let(:dummy_content) { <<-'EOF'
        この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。
    EOF
      }
    let(:blog) { described_class.create(title: 'test', content: dummy_content.strip) }
    subject { blog.truncated_content }
    context 'with no arguments' do
      it '30文字で切り捨てられること' do
        expect(subject.length).to eq(30)
      end
    end

    context 'with length arguments' do
      let(:length) { 10 }
      subject { blog.truncated_content(length: length) }
      it '10文字で切り捨てられること' do
        expect(subject.length).to eq(length)
      end
    end

    context 'with omission arguments' do
    let(:omission) { '・・・'}
      subject { blog.truncated_content(omission: omission) }
      it '末尾が指定された文字で終わること' do
        expect(subject[-3..-1]).to eq(omission)
      end
    end

   end
end

以前の記事で使用したコードを例にとって解説していきます。こちらはあるモデルのメソッドをテストするためのコードです。 例ではblogモデルのtruncated_contentというブログの文章を30文字で切り捨ててくれるメソッドのテストを書いています。

class Blog < ApplicationRecord
  belongs_to :category
  has_many :reviews
  has_many :review_items, through: :reviews
  has_many :review_item_masters, through: :review_items

  validates :content, length: { maximum: 140 }

  def truncated_content(length: 30, omission: '...')
    content.truncate(length, omission: omission)
  end
end

コード例解説

 

このテストコードを解説していくと、さきほどお話したようにRspecでは、describe, context, itはテストケースのグルーピングを行なっていきます。

 

構文 役割
describe どういったテストを書くのか記述する #contened_methodなどメソッド名
context どういった条件のテストか 引数が渡された場合、条件に一致するレコードがない、バリデーションエラーなど
it テストケース 末尾が指定された文字で終わること、レコードが作成されることなど
 

表にするとざっくりこのような使い分けになっており、describeでテスト全体をのお題目を宣言して、contextでそれぞれの条件のテストをグルーピングitでそれぞれのテストケースをテストするという形になります。

表の例には、文章形式で例をまとめましたが、describe,context,itは第一引数にそのテストの説明をかけるので表のれいに書いたような内容を一緒に記述しておくと「どういうテストが行われているのか?」「どういう振る舞いをすることが期待されるモジュールなのか?」ということが明白になります。テストを書く際は例を参考にしながら、うまくテストをグルーピングできるとよいでしょう。

 

テスト結果を確認するexpect

 

expectは実際にテストを実施する部分です。このexpectはit句の中で使用できる構文で以下のようにテスト結果と期待する値を記述することでテストを実施します。

 

it { expect( 1 + 1 ).to eq(2) }
it { expect( 1 + 1 ).to_not eq(5) }

  この例ではマッチャにeqメソッドを使用していますが、他にもさまざまなマッチャがあります。(ここでは、本筋とそれるので説明は別の機会にします。) expectはit句の中に複数書くことが可能ですが原則として1つのitに対して1つのexpectが保守性の観点から望ましいです。(複数のexpectがあった場合にテストが失敗するとどこでエラーになったかがわかりづらい)  

まとめ

 

今回はRspecのdescribe,context,it,expectの構文を説明しましたが、Rspecにはもう少し覚えておきたい構文が存在します。一気に全部を説明すると覚えるのも大変なので この記事での説明はここまでとします。他にもテストをスッキリ書くためのsubjectやbefore,let構文などが使えるとより簡潔にテストコードを記述できるようになるのでそちらも別の機会に説明できればと思います。