Как выполнять вход и выход пользователей для тестирования с помощью Rspec + Devise + FactoryGirl

Я новичок в Rspec, но мне удалось собрать рабочую (по крайней мере, в моих тестах) настройку, которая позволяет мне тестировать различное поведение в состояниях входа / выхода с помощью помощников FactoryGirl + Devise и Warden. Процесс состоит из следующих основных шагов:

  1. Заводская девушка определяет универсального пользователя
  2. Каждый тестовый блок, требующий входа в систему, использует ловушку before (: each) для входа пользователей в систему.
  3. Конфигурация rails_helper разрушает логин пользователя после каждого теста с помощью after: each

Я просмотрел много примеров кода, чтобы заставить это работать, но я еще не нашел полного пути туда и обратно, и хотя я знаю, что это работает в моей настройке, мне интересно, правильно ли это, в частности, я дублирование чего-либо излишне (например, пользовательский вход в разрывы) или создание неожиданного поведения в будущем.

Вот соответствующий код для каждого шага и образец теста:

spec / factoryies.rb

FactoryGirl.define do

  factory :user do
    sequence(:name)       { |n| "person #{n}"}
    sequence(:email)      { |n| "person#{n}@example.com" }
    password              'foobar'
    password_confirmation 'foobar'
    confirmed_at          Time.now
    sequence(:id)         { |n| n }
  end
end

spec / rails_helper.rb

...
  # Add login/logout helpers from Devise
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view

  # Include Warden test helpers specifically for login/logout
  config.include Warden::Test::Helpers

  # Add capybara DSL
  config.include Capybara::DSL

  # Tear down signed in user after each test
  config.after :each do
    Warden.test_reset!
  end

spec / views / static_pages (образец теста)

RSpec.describe 'static_pages home, signed in', type: :view do
  before(:each) do
    @user = build(:user)
    login_as(@user)
  end

  it 'should display the correct links when signed in' do

    visit root_path

    # links which persist in both states
    expect(page).to have_link('Site Title', href: root_path, count: 1)

    # links which drop out after login
    expect(page).not_to have_link('Login', href: new_user_session_path)
    expect(page).not_to have_link('Join', href: signup_path)

    # links which are added after login
    expect(page).to have_link('Add Item', href: new_item_path)
    expect(page).to have_link('My Items', href: myitems_path)
  end
end

person oneWorkingHeadphone    schedule 20.02.2017    source источник


Ответы (1)


Ваша настройка полностью в порядке. Одна вещь, как сказал @Greg Tarsa, заключается в том, что вы можете проводить такие тесты на уровне функций. Еще одна вещь от меня заключается в том, что нужно использовать одну единственную спецификацию для тестирования одной единственной вещи, например. он должен быть одиночным (или несколькими) expect в it блоке. Но это не строгое правило - решать вам.

И я провел некоторый рефакторинг вашей установки с использованием предыдущих советов и синтаксиса функционального стиля. Может быть, было бы полезно:

  background do
    @user = build(:user)
    login_as(@user)
    visit root_path
  end

  scenario "links persist in both states" do
    expect(page).to have_link('Site Title', href: root_path, count: 1)
  end

  scenario "links dropped out after login" do
    expect(page).not_to have_link('Login', href: new_user_session_path)
    expect(page).not_to have_link('Join', href: signup_path)
  end

  scenario "links added after login" do
    expect(page).to have_link('Add Item', href: new_item_path)
    expect(page).to have_link('My Items', href: myitems_path)
  end
person VAD    schedule 21.02.2017