0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsチュートリアル テストをRSpecで実施 【フィーチャスペック編 users_login_spec 3/7】

Last updated at Posted at 2018-08-10

テスト対象

該当するコントローラ 該当するアクション
SessionsController new, create, destroy

環境

Userモデル 単体テスト編 1/3 に記載

フォルダ、使用ファイル

種類 ファイル名
スペック 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
    
    :support_module.rb
    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) の部分

    :support_module.rb
    # 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


参考


参考


続く

フィーチャスペック編 users_profile_spec 4/7

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?