はじめに
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を用いて記述量を少なくすればいいのではないかと思います。
一番は楽しく書くことで、テストが実行し通った時の嬉しさを味わってもらいたいです笑