RSpecテストとは
Railsでよくつかわれるテストツール。
「人間が読んでも分かりやすいコードでテストを書くこと」を目的としている。
Gemをインストールして、簡単にテストできる。
describe
これから○○のテストを始めるよと、テストのタイトル的な感じ。
describe 'ログインのテスト' do
end
describe '新規登録のテスト' do
end
describe '商品管理機能のテスト' do
end
context
describeをパターン分けをして、状況ごとにテストの流れを整理する。
ログインのテストなら、成功・失敗などパターンが発生するので、下記のように分岐させる。
describe 'ログインのテスト' do
context 'ログイン成功した場合のテスト' do
end
context 'ログイン失敗した場合のテスト' do
end
end
describe '商品管理機能のテスト' do
context '商品が正しく登録される場合のテスト' do
end
context '商品登録が失敗する場合のテスト' do
end
end
it
パターン分けした後に、どのような状態になってることを確認したいのか、具体的に。
describe 'ログインのテスト' do
context 'ログイン成功した場合のテスト' do
it 'ログイン後のリダイレクト先が正しいか' do
end
end
context 'ログイン失敗した場合のテスト' do
it 'ログイン失敗後のリダイレクト先が正しいか' do
end
end
end
describe '商品管理機能のテスト' do
context '商品が正しく登録される場合のテスト' do
it '保存された商品の情報が正しいか' do
end
end
context '商品登録が失敗する場合のテスト' do
it 'エラーメッセージが正しいか' do
end
end
end
expect( ).to と eq
expect( ).to
は、( )内を期待値とする。
eq
は、その期待とeqの後に続く値が同じかを確認。
expect( ).to
を エクスペクテーション
、
eq
を マッチャー
と呼ぶ。
下記は、「ログイン後、example.com/users/1にリダイレクトする」ようチェックしてる
current_path
:
現在のページのパスを取得する。
.to eq
:
その後の値と等しいか確認。この場合「current_path」と等しいか。
'/users/' + user.id.to_s
:
ユーザIDをto_sで文字列にし、それをusersと結合する。
例えば、user.id が 1 の場合、「/users/1」とする。
describe 'ログインのテスト' do
context 'ログイン成功した場合のテスト' do
it 'ログイン後のリダイレクト先が正しいか' do
expect(current_path).to eq '/users/' + user.id.to_s
end
end
end
describe '商品管理機能のテスト' do
context '商品が正しく登録される場合のテスト' do
it '保存された商品の情報が正しいか' do
product = Product.create(name: 'サンプル商品', price: 1000)
# 商品の名前と価格が正しいかを確認
expect(product.name).to eq('サンプル商品')
expect(product.price).to eq(1000)
end
end
context '商品登録が失敗する場合のテスト' do
it 'エラーメッセージが正しいか' do
# 商品名が空の場合
product = Product.create(name: '', price: 1000)
# 商品名が空だとエラーメッセージが表示されることを確認
expect(product.errors[:name]).to eq(["can't be blank"])
end
end
end
他にもよく使われるマッチャー:
-
be
:
オブジェクトが同一であるかを確認(例:expect(obj1).to be obj2
)。 -
include
:
配列やハッシュに特定の要素が含まれているかを確認(例:expect(array).to include value
)。 -
match
:
正規表現に一致するかを確認(例:expect(string).to match /pattern/
)。
before
「フック」と呼ぶ。
個々のテストを実行する前に、まとめて共通する部分の前処理をする。
例えば、以下のようなログインのテストの場合、ログインするためのメールアドレスや名前が必要になる。
beforeを使うと、テストの度毎回書く必要がなく、まとめて書くことができる。
-
fill_in 'user[name]', with: user.name
- 「名前」入力欄に、
user.name
(テスト用のユーザーの名前)を入力させる。
- 「名前」入力欄に、
-
fill_in 'user[password]', with: user.password
- 「パスワード」入力欄に、
user.password
(テスト用のユーザーのパスワード)を入力させる。
- 「パスワード」入力欄に、
-
click_button 'Log in'
- 「ログイン」ボタンをクリックさせる。
beforeを使わないと…
# beforeを使わなかった場合
describe 'ログインのテスト' do
context 'ログイン成功した場合のテスト' do
it 'ログイン後のリダイレクト先が正しいか' do
# ログイン処理を毎回書く必要がある
fill_in 'user[name]', with: user.name
fill_in 'user[password]', with: user.password
click_button 'Log in'
expect(current_path).to eq '/users/' + user.id.to_s
end
it 'ログイン後にユーザー名が表示されるか' do
# ここでも同じ処理を繰り返し書かないといけない
fill_in 'user[name]', with: user.name
fill_in 'user[password]', with: user.password
click_button 'Log in'
expect(page).to have_content user.name
end
end
end
beforeを使うと…
# beforeを使った場合
describe 'ログインのテスト' do
context 'ログイン成功した場合のテスト' do
# ここにまとめて書ける!コードが簡潔!
before do
fill_in 'user[name]', with: user.name
fill_in 'user[password]', with: user.password
click_button 'Log in'
end
it 'ログイン後のリダイレクト先が正しいか' do
expect(current_path).to eq '/users/' + user.id.to_s
end
it 'ログイン後にユーザー名が表示されるか' do
expect(page).to have_content user.name
end
end
end