Capybara 测试没有通过数据库清理器,必须 运行 两次没有 database_cleaner 才能通过

Capybara test doesn't pass with database cleaner, must be run twice without database_cleaner to pass

我正在尝试使用水豚测试下拉菜单。如果我不清理数据库,它工作正常。我必须清理数据库以使其他测试正常运行。

config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end
  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation, {:except => %w[questions]}
  end
  config.before(:each) do
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end

如果我注释掉数据库清理器,则测试必须 运行 至少两次才能通过。我可以看到它重试并始终以相同的标准通过第二次尝试。一旦数据库清理器就位,测试参数就会在每次迭代中发生变化,因此它没有机会对其进行第二次测试。

 context 'when there are questions and answers in the system' do
        before do
          allow_any_instance_of(Form).to receive(:create_questions)
          question = create(:question)
          people.map do |person|
            create(:answer, question: question, person: person) if [true, false].sample
          end
        end

        it 'should allow filtering by whether a person has answered a specific question', js: true do
          @question = Question.first
          select_from_dropdown @question.text, from: 'question'
          click_on 'Search'
          people.each do |person|
            if person.questions.include? @question
              expect(page).to have_content person.full_name
            else
              expect(page).to_not have_content person.full_name
            end
          end
        end
      end

这是探索水豚下拉菜单的辅助方法

  def select_from_dropdown(item_text, options)
    # find dropdown selector
    dropdown = find_field(options[:from], visible: false).first(:xpath, './/..')
    # click on dropdown
    dropdown.trigger('click')
    # click on menu item
    dropdown.find('.menu .item', text: item_text, visible: false).trigger('click')
  end

我在整个 select_from_dropdown 期间都尝试过 sleep,我认为可能加载速度不够快,但这不是问题所在。理想情况下,此测试应该在第一次尝试时就可以运行,但至少需要通过数据库清理器才能通过。

测试中没有 visit 显示,这意味着您在创建问题之前访问过该页面,因此页面上没有显示预期的信息。如果您不清除数据库,那么数据将从第一个 运行 存在到第二个 运行,这解释了为什么它第二次通过。您应该始终在创建测试数据后访问该页面。

此外,正如我在评论中提到的,您可能想要修复(如果使用 Rails 5.1+,则删除)您的 DatabaseCleaner 配置和 trigger 的使用在测试中是一个非常糟糕的主意,因为它可以做用户永远做不到的事情。