テスト対象
該当するコントローラ | 該当するアクション |
---|---|
SessionsController | new, create, destroy |
環境
フォルダ、使用ファイル
種類 | ファイル名 |
---|---|
スペック | spec/features/users_login_spec.rb |
サポートモジュール | spec/support/support_module.rb |
shared_examples | spec/support/shared_examples.rb |
shared_context | spec/support/shared_context.rb |
ファクトリ(ユーザ) | spec/support/factories/users.rb |
アウトライン作成 1/2
users_login_spec.rb
# spec/features/users_login_spec.rb
RSpec.feature "UsersLogin", type: :feature do
# ログインページ
describe "log in"
# loginフォームが正しいこと
it_behaves_like "log in form have right css"
# 情報が valid
context "valid info"
# 成功
scenario "success log in"
# 情報が invalid
context "invalid info"
# 失敗
scenario "fail log in"
end
スペック作成 1/2
users_login_spec.rb
# spec/features/users_login_spec.rb
require 'rails_helper'
RSpec.feature "UsersLogin", type: :feature do
include SupportModule
include_context "setup"
subject { page }
describe "log in" do
before { visit "/login" }
# loginフォームが正しいこと
it_behaves_like "login-form have right css"
# ログイン情報が 有効
context "valid info" do
scenario "success log in" do
visit "/login"
fill_in_login_form(user) # => support_module
click_button "Log in"
should have_title(user.name)
should have_css('h1', text: user.name)
should have_current_path(user_path(user))
end
end
# ログイン情報が 無効
context "invalid info" do
scenario "fail log in" do
visit login_path
fill_in_login_form(user, invalid: true) # => support_module
click_button "Log in"
error_messages "Invalid email/password combination"
should have_title("Log in")
should have_css("h1", text: "Log in")
should have_current_path("/login")
end
end
end
end
shared_examples の作成
-
it_behaves_like "login-form have right css"
の部分
shared_examples.rb
# spec/support/shared_examples.rb
# login form
# sessions#new
shared_examples_for "login-form have right css" do
it { expect(page).to have_css('label', text: 'Email') }
it { expect(page).to have_css('label', text: 'Password') }
it { expect(page).to have_css('input#session_email') }
it { expect(page).to have_css('input#session_password') }
it { expect(page).to have_css('input#session_remember_me[type="checkbox"]') }
it { expect(page).to have_css('label.checkbox.inline', text: 'Remember me') }
it { expect(page).to have_button('Log in') }
end
SupportModule, shared_context, ファクトリ
-
SupportModule
-
fill_in_login_form(user)
(ログイン情報が 有効/無効) -
error_messages "Invalid email/password combination"
の部分
-
support_module.rb
# spec/support/support_module.rb
module SupportModule
def fill_in_login_form(user, option = { invalid: false })
if option[:invalid]
fill_in "Email", with: ""
fill_in "Password", with: ""
else
fill_in "Email", with: user.email
fill_in "Password", with: user.password
end
end
end
module SupportModule
def error_messages(msg = "")
# should have_css('div#error_explanation')
# should have_css('div.alert.alert-danger') if msg.empty? and return
if msg.empty?
should have_css('div.alert.alert-danger')
else
should have_css('div.alert.alert-danger', text: msg)
end
end
end
- shared_context
shared_context
# spec/support/shared_context.rb
RSpec.shared_context "setup" do
# 遅延評価、呼ばれた時にDB保存される
let(:user) { create(:user) }
end
- ファクトリ(ユーザ)
users.rb
# spec/support/factories/users.rb
FactoryBot.define do
# 自分
# factory [任意のファクトリ名], class: [クラス名]
factory :user, class: User do
name "Example user"
email "user@example.com"
password "foobar"
password_confirmation "foobar"
admin false
end
実行結果 1/2
$ bin/rspec spec/features/users_login_spec.rb -e "log in"
UsersLogin
log in
behaves like login-form have right css
should have visible css "label" with text "Email"
should have visible css "label" with text "Password"
should have visible css "input#session_email"
should have visible css "input#session_password"
should have visible css "input#session_remember_me[type=\"checkbox\"]"
should have visible css "label.checkbox.inline" with text "Remember me"
should have visible button "Log in"
valid info
success log in
invalid info
fail log in
Finished in 4.9 seconds (files took 2.28 seconds to load)
9 examples, 0 failures
アウトライン作成 2/2
users_login_spec.rb
# spec/features/users_login_spec.rb
RSpec.feature "UsersLogin", type: :feature do
# (省略)
# ログアウト
describe "log out"
# ログアウトが正常にできること
describe "success log out"
# 同じサイトを 複数tab/window で開いている状態をシュミレート
context "when open in some browser-tab(or window)"
# "Log out" をクリック 1回目をシュミレート
scenario "1st time log out"
# "Log out" をクリック 2回目をシュミレート
scenario "2nd time log out"
end
スペック作成 2/2
users_login_spec.rb
# spec/features/users_login_spec.rb
require 'rails_helper'
RSpec.feature "UsersLogin", type: :feature do
include SupportModule
include_context "setup"
subject { page }
# (省略)
# ログアウト
describe "log out" do
# ログアウトが正常にできること
describe "success log out" do
# 同じサイトを 複数tab/window で開いている状態をシュミレート
context "when open in some browser-tab(or window)" do
# "Log out" をクリック 1回目をシュミレート
scenario "1st time log out" do
login_as(user)
click_link "Log out"
should have_current_path(root_path)
end
# "Log out" をクリック 2回目をシュミレート
# HTTPリクエストを直接送るので、type: :request オプションをつける
scenario "2nd time log out", type: :request do
delete logout_path(user)
should have_current_path(root_path)
end
end
end
end
end
SupportModule
-
login_as(user)
の部分
# spec/support/support_module.rb
module SupportModule
def login_as(user)
visit root_path
click_link "Log in"
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Log in"
end
end
実行結果 2/2
$ bin/rspec spec/features/users_login_spec.rb -e "log out"
UsersLogin
log out
success log out
when open in some browser-tab(or window)
1st time log out
2nd time log out
Finished in 5.62 seconds (files took 2.19 seconds to load)
2 examples, 0 failures