使用 Rails 5.1 和 Vue.js 进行不稳定的系统测试

Flaky system test with Rails 5.1 and Vue.js

几天来我一直在尝试对此进行调试,只是无法弄清楚问题出在哪里。本来以为是顺序依赖,后来觉得不是了所以rspec --bisect=verbose.

我现在倾向于 Devise/Warden 助手工作不正常,我没有正确设置 capybara/web 驱动程序或其他原因。

此测试有时失败:

  1. 重定向时,从菜单中选择项目时重定向到另一个页面。比如例子 redirects to Account Settings page after pressing Account Settings。这是我责怪 Devise 助手的地方,因为当我登陆主页时我已经登录,但是当我进入帐户设置时 current_user returns nil,因此示例失败了重定向到登录页面。

这也是特定于测试的,实时代码几个月没有问题。

系统测试

require 'rails_helper'

RSpec.describe 'home page', type: :system do
  before(:context) do
    WebMock.disable_net_connect!(allow_localhost: true)
  end

  after(:each) do
    Warden.test_reset!
  end

  context 'when not logged in' do
    it 'displays login with discord button' do
      visit '/'

      expect(page).to have_content 'Login with Discord'
    end

    it 'logs in with discord after clicking Login with Discord' do
      OmniAuth.config.test_mode = true

      visit '/'

      click_on 'Login with Discord'

      expect(page).to_not have_content 'Login with Discord'

      find('.profile-menu').hover

      expect(page).to have_content 'Account Settings'
      expect(page).to have_content 'Event Calendar'
      expect(page).to have_content 'Logout'
    end
  end

  context 'when logged in' do
    context 'as an average user' do
      before do
        @user = build(:user, confirmed_at: Time.now)
        create(:profile, user: @user)

        login_as(@user, scope: :user)
      end

      it 'shows profile menu' do
        visit '/'

        find('.profile-menu').hover

        expect(page).to have_content 'Account Settings'
        expect(page).to have_content 'Event Calendar'
        expect(page).to have_content 'Logout'
      end

      it 'logs user out after pressing Logout' do
        visit '/'

        find('.profile-menu').hover
        find('.logout').click

        expect(page).to have_content 'Login with Discord'
      end

      it 'redirects to Events page after pressing Event Calendar' do
        event = create(:event)

        visit '/'

        find('.profile-menu').hover
        find('.event-calendar').click

        expect(page).to have_content event.title
      end

      it 'redirects to Account Settings page after pressing Account Settings' do
        visit '/'

        find('.profile-menu').hover
        find('.settings').click

        expect(page).to have_content 'Account Settings'
      end
    end

    context 'as an organiser' do
      before do
        @user = build(:user, confirmed_at: Time.now, role: :organiser)
        create(:profile, user: @user)

        login_as(@user, scope: :user)
      end

      it 'shows profile menu with Organiser Dashboard link' do
        visit '/'

        find('.profile-menu').hover

        expect(page).to have_content 'Organiser Dashboard'
      end

      it 'redirects to Organiser Dashboard page after pressing Organiser Dashboard' do
        visit '/'

        find('.profile-menu').hover
        find('.organiser-dashboard').click

        expect(page).to have_content 'Create Event'
      end
    end
  end
end

设计配置

require 'devise'

RSpec.configure do |config|
  config.include Warden::Test::Helpers
end

Javascript 驱动菜单重定向

handleCommand(command) {
  if (command === "logout") {
    Rails.ajax({
      url: "/sign_out",
      type: "DELETE",
      dataType: "json",
      success: (signed_in_status) => {
        this.$store.commit('authenticate', false)
        this.$message.success('You logged out');
        location.href = "/";
      },
      error: (signed_in_status) => {
        this.$store.commit('authenticate', true)
        this.$message.error('Something went wrong');
      }
    })
  }
  else if (command === "settings") {
    location.href = "/users/edit";
  }
  else if (command === "events") {
    location.href = "/events";
  }
  else if (command === "organiser") {
    location.href = "/admin/events";
  }
}

我似乎已经解决了这个问题。我已经尝试了这个 SO 答案中提到的几件事。据我所知,修复它的是什么修复了我的配置:

 RSpec.configure do |config|
   config.include Warden::Test::Helpers
 end

 RSpec.configure do |config|
   config.include Devise::Test::IntegrationHelpers, type: :system
 end

这也让我放弃了:

  after(:each) do
    Warden.test_reset!
  end

在我所有的测试中。我已经 运行 进行了相当多的测试并且它们不再失败,所以我现在假设这确实已经修复。