RSpecでのテスト入門〜よく使う機能 + 見やすいテストを書く編〜
- 前回は基本の基本を書きました。Rspecでのテスト入門~E2E(System)テスト基本文法編~
- 今回は一段上がって基本的な機能をアウトプット!!
まずはテストの流れを母国語で
- 対象を決める(機能・処理・画面・メソッド)
- 条件を決める(〜が〜の時。)※主語を書くこと
- 条件に対するテストを記述する
- 期待するアウトプットが返ってくるかを確認する
使い分け(describe/context/example/it)
- ここで出てきた
テストの対象
と特定の条件
とアウトプット
に注目して、(describe/context/example/it)の使い分けを行う。
- describe:
テストの対象が何かを記述する
- メソッド名,機能,〜処理,〜画面(E2Eテスト)
- context:
特定の条件が何かを記述する
- 奇数・偶数の時,
- example・it:
アウトプットが何かを記述する
- 日本語で記述するときは
example
を使う。
- it "is 〜やit { should be 〜 }のような形で書きたい場合は
it
を使う。
テンプレートとサンプル
- テンプレート
hoge_spec.rb
describe 'テストの対象' do
context '特定の条件の内容' do
example 'アウトプットの内容' do
...テスト処理...
end
it "is 〜" do ...テスト処理... end
it { should_be 〜 }
end
end
- サンプル(FizzBazz)
fizzbuzz_spec.rb
describe 'FizzBuzz' do
describe '#run' do
context '3の倍数' do
example 'Fizzという文字列を返すこと' do
expect(FizzBuzz.run(3)).to eq('Fizz')
expect(FizzBuzz.run(6)).to eq('Fizz')
end
end
context '5の倍数' do
example 'Buzzという文字列を返すこと' do
expect(FizzBuzz.run(5)).to eq('Buzz')
expect(FizzBuzz.run(10)).to eq('Buzz')
end
end
context '3の倍数かつ5の倍数' do
example 'FizzBuzzという文字列を返すこと' do
expect(FizzBuzz.run(15)).to eq('FizzBuzz')
end
end
context '3の倍数ではない かつ 5の倍数ではない' do
example 'そのままの数字を返すこと' do
expect(FizzBuzz.run(1)).to eq(1)
expect(FizzBuzz.run(2)).to eq(2)
end
end
end
end
変数名を見ただけで何をやっているか想像できるようにする
- 悪い例)
question1
,question2
とか...(マジックナンバーを使用した変数)
- 良い例)
question_without_title
(【タイトルが無い質問】と想像がつく)
let
でオブジェクトを定義して使用する
- 以下がわかりやすかったです。
- RSpecのletを使うのはどんなときか?(翻訳)
let
での共通化とlet!
-
let
では共通化したい定義などをdiscribe
直下に書き、使いたいところで使用することが多いようです。
question_spec.rb
describe 'QandA管理機能', type: :system do
# ユーザA,Bを定義(初めて呼び出された時に生成されるので使用には注意が必要
let(:user_a) { FactoryBot.create(:user, name: 'ユーザA', email: '[email protected]') }
let(:user_b) { FactoryBot.create(:user, name: 'ユーザB', email: '[email protected]') }
# 事前に評価されるのでit内のような使い方ができる
let!(:question_a) { FactoryBot.create(:question, name: 'name',title: 'test question A',content: 'test Aだよ',author: 'ユーザA',user: user_a) }
it 'ブログの取得ができること' do
expect(Blog.first).to eq blog
end
let
は遅延評価・let!
は事前評価
- 先ほどのコードで出てきた
let!
の部分ですがこれをlet
としてしまうとエラーになります。letの内容は初めて呼び出した時に生成されるためです。もしlet
で書きたかったらbefore
ブロックを使用して書くことができます。
let
と同じような機能にsubject
がある
- ここで出てきた
テストの対象
と特定の条件
とアウトプット
に注目して、(describe/context/example/it)の使い分けを行う。 - describe:
テストの対象が何かを記述する
- メソッド名,機能,〜処理,〜画面(E2Eテスト)
- context:
特定の条件が何かを記述する
- 奇数・偶数の時,
- example・it:
アウトプットが何かを記述する
- 日本語で記述するときは
example
を使う。 - it "is 〜やit { should be 〜 }のような形で書きたい場合は
it
を使う。
- 日本語で記述するときは
テンプレートとサンプル
- テンプレート
hoge_spec.rb
describe 'テストの対象' do
context '特定の条件の内容' do
example 'アウトプットの内容' do
...テスト処理...
end
it "is 〜" do ...テスト処理... end
it { should_be 〜 }
end
end
- サンプル(FizzBazz)
fizzbuzz_spec.rb
describe 'FizzBuzz' do
describe '#run' do
context '3の倍数' do
example 'Fizzという文字列を返すこと' do
expect(FizzBuzz.run(3)).to eq('Fizz')
expect(FizzBuzz.run(6)).to eq('Fizz')
end
end
context '5の倍数' do
example 'Buzzという文字列を返すこと' do
expect(FizzBuzz.run(5)).to eq('Buzz')
expect(FizzBuzz.run(10)).to eq('Buzz')
end
end
context '3の倍数かつ5の倍数' do
example 'FizzBuzzという文字列を返すこと' do
expect(FizzBuzz.run(15)).to eq('FizzBuzz')
end
end
context '3の倍数ではない かつ 5の倍数ではない' do
example 'そのままの数字を返すこと' do
expect(FizzBuzz.run(1)).to eq(1)
expect(FizzBuzz.run(2)).to eq(2)
end
end
end
end
変数名を見ただけで何をやっているか想像できるようにする
- 悪い例)
question1
,question2
とか...(マジックナンバーを使用した変数)
- 良い例)
question_without_title
(【タイトルが無い質問】と想像がつく)
let
でオブジェクトを定義して使用する
- 以下がわかりやすかったです。
- RSpecのletを使うのはどんなときか?(翻訳)
let
での共通化とlet!
-
let
では共通化したい定義などをdiscribe
直下に書き、使いたいところで使用することが多いようです。
question_spec.rb
describe 'QandA管理機能', type: :system do
# ユーザA,Bを定義(初めて呼び出された時に生成されるので使用には注意が必要
let(:user_a) { FactoryBot.create(:user, name: 'ユーザA', email: '[email protected]') }
let(:user_b) { FactoryBot.create(:user, name: 'ユーザB', email: '[email protected]') }
# 事前に評価されるのでit内のような使い方ができる
let!(:question_a) { FactoryBot.create(:question, name: 'name',title: 'test question A',content: 'test Aだよ',author: 'ユーザA',user: user_a) }
it 'ブログの取得ができること' do
expect(Blog.first).to eq blog
end
let
は遅延評価・let!
は事前評価
- 先ほどのコードで出てきた
let!
の部分ですがこれをlet
としてしまうとエラーになります。letの内容は初めて呼び出した時に生成されるためです。もしlet
で書きたかったらbefore
ブロックを使用して書くことができます。
let
と同じような機能にsubject
がある
hoge_spec.rb
describe 'テストの対象' do
context '特定の条件の内容' do
example 'アウトプットの内容' do
...テスト処理...
end
it "is 〜" do ...テスト処理... end
it { should_be 〜 }
end
end
fizzbuzz_spec.rb
describe 'FizzBuzz' do
describe '#run' do
context '3の倍数' do
example 'Fizzという文字列を返すこと' do
expect(FizzBuzz.run(3)).to eq('Fizz')
expect(FizzBuzz.run(6)).to eq('Fizz')
end
end
context '5の倍数' do
example 'Buzzという文字列を返すこと' do
expect(FizzBuzz.run(5)).to eq('Buzz')
expect(FizzBuzz.run(10)).to eq('Buzz')
end
end
context '3の倍数かつ5の倍数' do
example 'FizzBuzzという文字列を返すこと' do
expect(FizzBuzz.run(15)).to eq('FizzBuzz')
end
end
context '3の倍数ではない かつ 5の倍数ではない' do
example 'そのままの数字を返すこと' do
expect(FizzBuzz.run(1)).to eq(1)
expect(FizzBuzz.run(2)).to eq(2)
end
end
end
end
- 悪い例)
question1
,question2
とか...(マジックナンバーを使用した変数) - 良い例)
question_without_title
(【タイトルが無い質問】と想像がつく)
let
でオブジェクトを定義して使用する
- 以下がわかりやすかったです。
- RSpecのletを使うのはどんなときか?(翻訳)
let
での共通化とlet!
-
let
では共通化したい定義などをdiscribe
直下に書き、使いたいところで使用することが多いようです。
question_spec.rb
describe 'QandA管理機能', type: :system do
# ユーザA,Bを定義(初めて呼び出された時に生成されるので使用には注意が必要
let(:user_a) { FactoryBot.create(:user, name: 'ユーザA', email: '[email protected]') }
let(:user_b) { FactoryBot.create(:user, name: 'ユーザB', email: '[email protected]') }
# 事前に評価されるのでit内のような使い方ができる
let!(:question_a) { FactoryBot.create(:question, name: 'name',title: 'test question A',content: 'test Aだよ',author: 'ユーザA',user: user_a) }
it 'ブログの取得ができること' do
expect(Blog.first).to eq blog
end
let
は遅延評価・let!
は事前評価
- 先ほどのコードで出てきた
let!
の部分ですがこれをlet
としてしまうとエラーになります。letの内容は初めて呼び出した時に生成されるためです。もしlet
で書きたかったらbefore
ブロックを使用して書くことができます。
let
と同じような機能にsubject
がある
let
での共通化とlet!
-
let
では共通化したい定義などをdiscribe
直下に書き、使いたいところで使用することが多いようです。
question_spec.rb
describe 'QandA管理機能', type: :system do
# ユーザA,Bを定義(初めて呼び出された時に生成されるので使用には注意が必要
let(:user_a) { FactoryBot.create(:user, name: 'ユーザA', email: '[email protected]') }
let(:user_b) { FactoryBot.create(:user, name: 'ユーザB', email: '[email protected]') }
# 事前に評価されるのでit内のような使い方ができる
let!(:question_a) { FactoryBot.create(:question, name: 'name',title: 'test question A',content: 'test Aだよ',author: 'ユーザA',user: user_a) }
it 'ブログの取得ができること' do
expect(Blog.first).to eq blog
end
let
は遅延評価・let!
は事前評価
- 先ほどのコードで出てきた
let!
の部分ですがこれをlet
としてしまうとエラーになります。letの内容は初めて呼び出した時に生成されるためです。もしlet
で書きたかったらbefore
ブロックを使用して書くことができます。
let
と同じような機能にsubject
がある
let!
の部分ですがこれをlet
としてしまうとエラーになります。letの内容は初めて呼び出した時に生成されるためです。もしlet
で書きたかったらbefore
ブロックを使用して書くことができます。let
と同じような機能にsubject
がある
subjectもオブジェクトを定義しておけるという面ではletと似ているが以下のように使う
fuga_spec.rb
# 普通に文字列を定義している例
RSpec.describe User do
describe '#question' do
subject { '質問です' }
context 'question' do
it '質問が表示されていること' do
is_expected.to eq '質問です'
end
end
end
end
hoge_spec.rb
# リクエストをsubjectで定義している例
describe "GET 'index'" do
subject(:action) { get 'index' }
it { is_expected.to be_success } # OK
end
end
- このように、定義した
subject
を使用する時はis_expected
を使用します。
RSpecの書き方は人それぞれになりがちです。プロジェクトの発足時にルールを策定し徹底することで後から入ってくる人がわかりやすいテストを記述しましょう。
Author And Source
この問題について(RSpecでのテスト入門〜よく使う機能 + 見やすいテストを書く編〜), 我々は、より多くの情報をここで見つけました https://qiita.com/yosuke_takeuchi/items/329a04d9adba3ce0818e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .