RSpecの基本使い方講座

スポンサーリンク

はじめに

RSpec書くのめちゃくちゃ楽しいんですけど、基本的にRailsを習いたての方ってテストを書きたくない方が多いのがなんでだろうって思ってました。
思考した結果、
①Railsとはまた別の文法だったり使うメソッドが新しく増えたりして単純に食わず嫌いで意味わからん、放置。
②テストなんて書かなくたって動けばいいんだよ!
って思う人が多いのかなと。
テストの重要性についてお伝えして、書き方こうしましょう!っていう記事です笑
今回の記事に関しては、基本的なRSpecの書き方についてまとめます。

参考サイト

RSpecの公式サイトと伊藤さんという日本で一番RSpecを書いているかもしれない人のQiitaを読みました。
正直初心者の方はEveryday Rails買って読めばいいと思います笑
Project: RSpec Core 3.1
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
Everyday Rails – RSpecによるRailsテスト入門

RSpecのグループ分け

基本文法 describe

describeメソッドの基本構文

一番基本的なテストの書き方はこのような形です。

RSpec.describe 'このテストはどのようなグループか' do
  it '何を期待しているか' do
    expect(テストで期待していること).to eq (結果)
  end
end

describe メソッド

describeメソッドははテストのグループ化を宣言するためのメソッドです。
※RSpecはRSpecが用意しているオブジェクトでその中に組み込まれています。
describeとは「〜を記述する」「〜を説明する」という動詞です。

it ‘〜〜’ do end

do〜endで囲まれている通り、これもブロック要素です。
RSpecのテストはitで囲まれている範囲をexampleという単位でまとめます。
itの中のエクスペクテーションが全てOKならそのexampleはパスして次のexampleのチェックに向かいます。

.to やeqについて(マッチャ)

こちらはマッチャと呼ばれるメソッドで、期待しているものと結果を結びつけるためのメソッドです。
この理解が最初の難関かもしれません。。。
(僕がそうだったので笑)
~公式を見てもらえばわかる通り、膨大な量になるので別記事でまとめます。~
こちらの記事にまとめましたので、合わせて是非読んでみてください!
RSpecのマッチャを使いこなせ

具体的な書き方

こちらは使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」で見たものが一番わかりやすいと思うのですが、一応書いておきます。

RSpec.describe '四則演算' do
  it '1 + 1 は 2 になること' do
    expect(1 + 1).to eq 2
  end
end

# もちろん複数のitを繋げて書くこともできます。
RSpec.describe '四則演算' do
  it '1 + 1 は 2 になること' do
    expect(1 + 1).to eq 2
  end
  it '10 - 1 は 9 になること' do
    expect(10 - 1).to eq 9
  end
end

context(describe)メソッドで条件分岐

contextメソッドの基本構文

RSpec.describe 'このテストはどのようなグループか' do
  context 'グループ分けその1' do
    it '何を期待しているか' do
      expect(テストで期待していること).to eq (結果)
    end
  end
  context 'グループ分けその2' do
    it '何を期待しているか' do
      expect(テストで期待していること).to eq (結果)
    end
  end
end

同じようなテストを実行しようとすると条件が似ているけど、一部違うなどというケースがあるかと思います。
それを整理整頓するのがcontext(describe)メソッドです。
※僕はほぼcontextしか使っていなかったのですが、describeメソッドでもネストして書けます。最初グループ宣言をdescribeで行っているので分けたいだけです笑

contextとは「環境」、「文脈」という英語の名詞です。

具体的な書き方

RSpec.describe '四則演算' do
  context '足し算' do
    it '1 + 1 は 2 になること' do
      expect(1 + 1).to eq 2
    end
    it '2 + 2 は 4 になること' do
      expect(2 + 2).to eq 4
    end
  end

  context '引き算' do
    it '2 - 1 は 1 になること' do
      expect(2 - 1).to eq 1
    end
    it '3 - 1 は 2 になること' do
      expect(3 - 1).to eq 2
    end
  end
end

beforeメソッドで共有部分をまとめて定義

before do … end で囲まれた部分は各exampleの実行前に毎回実行されます。
どのexampleでも使うデータや処理について事前に定義しておき、記述量を減らすとより見やすいコードになります。

具体的な書き方

RSpec.describe '四則演算' do
    before do
      @num =  10 * 10
    end
  context '足し算' do
    it '100 + 1 は 101 になること' do
      expect(@num + 1).to eq 101
    end
    it '100 + 2 は 102 になること' do
      expect(@num+ 2).to eq 102
    end
  end

  context '引き算' do
    it '100 - 1 は 99 になること' do
      expect(@num - 1).to eq 99
    end
    it '100 - 2 は 98 になること' do
      expect(@num - 2).to eq 98
    end
  end
end

現場でよく使われる変数宣言 letメソッド

beforeメソッドを使って共通する部分をまとめましたが、その際にインスタンス変数にデータを格納しました。
しかし、RSpecではこのインスタンス変数をletメソッドを使って置き換えることができます。

letメソッドの基本構文

let(:変数名) { データの中身 }

よく勘違いされるのが中に連想配列(Rubyではハッシュ)のデータを格納するときで、

let(:params) { { key1: value1 }, { key2: value2 } }

のように{}が重なることが要注意です。
※一番外の{}はあくまでRubyのブロック要素で、中の{}は連想配列のためのものということです!

具体的な書き方

RSpec.describe '四則演算' do
    before do
      let(:num) { 10 * 10 }
    end
  context '足し算' do
    it '100 + 1 は 101 になること' do
      expect(num + 1).to eq 101
    end
    it '100 + 2 は 102 になること' do
      expect(num+ 2).to eq 102
    end
  end

  context '引き算' do
    it '100 - 1 は 99 になること' do
      expect(num - 1).to eq 99
    end
    it '100 - 2 は 98 になること' do
      expect(num - 2).to eq 98
    end
  end
end

subjectメソッドを使ってテストしたいオブジェクトをまとめる

テストしたいオブジェクト(またはメソッドの実行結果)が明確に一つに決まっている場合は、subjectメソッドという機能を使ってテストコードをDRYにすることができます。

subjectメソッドの基本構文

RSpec.describe '題名' do
  subject { テストしたいオブジェクト }
    it 'グループ化したテスト' do
      is_expected.to eq '中身'
    end
end

# 省略形
RSpec.describe '題名' do
  subject { テストしたいオブジェクト }
    it { is_expected.to eq '中身' }
end

subjectメソッドを使った時の先ほどまでと違う点は「エクスペクテーションの書き方」です
expectメソッドの引数を書く必要がなく、is_expectedメソッドを使って省略することが可能です。

具体的な書き方

RSpec.describe '四則演算' do
    before do
      let(:multi) { 10 * 10 }
    end
  context '足し算' do
    subject { multi + num }
      it '100 + 1 は 101 になること' do
        let(:num) { 1 }
        is_expected.to eq 101
      end
      it '100 + 2 は 102 になること' do
        let(:num) { 2 }
        is_expected.to eq 102
      end
    end

  context '引き算' do
    subject { multi - num }
    it '100 - 1 は 99 になること' do
        let(:num) { 1 }
        is_expected.to eq 99
    end
    it '100 - 2 は 98 になること' do
        let(:num) { 2 }
        is_expected.to eq 98
    end
  end
end

終わりに

色々書きましたが、相手にわかりやすいテストコードを書くのが一番です!
たまに自分がどういうテストを実行しているのか、使っているメソッドはそもそもどういうものなのかを理解しないまま使っているとテストコードもぐちゃぐちゃになってしまうかなと。

最初にざっくり基本文法で記述し、最後にリファクタリングを行ってletやsubjectを用いて記述量を少なくすればいいのではないかと思います。

一番は楽しく書くことで、テストが実行し通った時の嬉しさを味わってもらいたいです笑

未経験者から最強のRailsエンジニアになるためのロードマップ
webアプリエンジニアになるためにどの程度学習すべきかをまとめた記事です。
タイトルとURLをコピーしました