malcoauri
malcoauri

Reputation: 12179

RSpec scenario refactoring

There are some RSpec integration tests:

require 'spec_helper'

feature 'Authentication', js: true do
  scenario 'Successfully Sign In' do
    user = create(:user)
    visit '/admin/signin'
    expect(page).to have_content('Login to Admin Panel')
    fill_in 'Email', with: user.email
    fill_in 'Password', with: user.password
    click_button 'Login'
    expect(page).to have_content('Welcome to the administrative panel of "Hotels" service!')
  end

  scenario 'Failed Sign In' do
    user = create(:user)
    visit '/admin/signin'
    expect(page).to have_content('Login to Admin Panel')
    fill_in 'Email', with: user.email + '_wrong'
    fill_in 'Password', with: user.password
    click_button 'Login'
    expect(page).to have_content('Invalid username/password')
  end

  scenario 'Repeated Sign In' do
    user = create(:user)
    visit '/admin/signin'
    expect(page).to have_content('Login to Admin Panel')
    fill_in 'Email', with: user.email
    fill_in 'Password', with: user.password
    click_button 'Login'
    visit '/admin/signin'
    expect(page).to have_content('Welcome to the administrative panel of "Hotels" service!')
  end

  scenario 'Sign Out' do
    user = create(:user)
    visit '/admin/signin'
    expect(page).to have_content('Login to Admin Panel')
    fill_in 'Email', with: user.email
    fill_in 'Password', with: user.password
    click_button 'Login'
    click_link 'Sign out'
    expect(page).to have_content('Login to Admin Panel')    
  end
end

As you can see these tests are very similar, and I hope there is some ability to refactor it. I heard about shared_examples, but I don't understand about this conception in scenarios. Please, give me some advice how I can improve my feature tests. Thanks!

Upvotes: 0

Views: 121

Answers (2)

juhlila
juhlila

Reputation: 1122

In addition to @Pavan answer, you definitely should use before :each in this case, so your whole test would be like this:

feature 'Authentication', js: true do
   before :each do
      user = create(:user)
      sign_in(user.email, user.password)
   end

   scenario 'Successfully Sign In' do
      expect(page).to have_content('Welcome to the administrative panel of "Hotels" service!')
   end

   scenario 'Repeated Sign In' do
      visit '/admin/signin'
      expect(page).to have_content('Welcome to the administrative panel of "Hotels" service!')
   end

   scenario 'Sign Out' do
      click_link 'Sign out'
      expect(page).to have_content('Login to Admin Panel')    
   end
 end

you can read more about Rspec before/after hooks here

Upvotes: 0

Pavan
Pavan

Reputation: 33542

I would put those repeated code in a helper file under /spec/support/ like this

module Features
  module SessionHelpers
    def sign_in(email, password)  
    visit '/admin/signin'
    expect(page).to have_content('Login to Admin Panel')
    fill_in 'Email', with: email
    fill_in 'Password', with: password
    click_button 'Login'
    end
  end
end

And call that method in every scenario like this

scenario 'Successfully Sign In' do
   user = create(:user)
   sign_in(user.email, user.password)
   expect(page).to have_content('Welcome to the administrative panel of "Hotels" service!')
end

Upvotes: 1

Related Questions