RSpec 只有第一个 `it` 阻止传递并且 Capybara 或 Selenium 重定向页面

RSpec only first `it` block passes and Capybara or Selenium redirects page

我有一个相当简单的测试场景,配置了 RSpec、Capybara 和 Selenium:

require './spec_helper'

RSpec.describe 'test' do
  title = 'My title'

  context 'When I navigate to my page' do
    before(:all) do
      visit 'http://foo.com/'
    end

    it "the page title is #{title}" do
      expect(page.title).to eq(title)
    end

    it 'there is an input for email' do
      expect(page).to have_css('#login-u')
    end

    it 'there is an input for password' do
      expect(page).to have_css('#login-p')
    end

    it 'there is an input for access token' do
      expect(page).to have_css('#login-a')
    end
  end
end

页面导航到,第一个 it 通过,然后页面重定向到空白页面,最后三个 it 块失败。

有趣的是,如果我将每个 expect 语句移动到第一个 it 块中,则测试通过:

require './spec_helper'

RSpec.describe 'test' do
  title = 'My title'

  context 'When I navigate to my page' do
    before(:all) do
      visit 'http://foo.com/'
    end

    it "the page title is #{title}" do
      expect(page.title).to eq(title)
      expect(page).to have_css('#login-u')
      expect(page).to have_css('#login-p')
      expect(page).to have_css('#login-a')
    end
  end
end

这是我的 Gemfile 的内容:

source "https://rubygems.org"

gem 'rspec', '~> 3.0'
gem 'selenium-webdriver'
gem 'capybara'

这是我的 spec_helper.rb:

require 'rubygems'
require 'bundler/setup'
require 'rspec'
require 'selenium-webdriver'
require 'capybara/rspec'

Capybara.default_driver = :selenium

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end

  config.shared_context_metadata_behavior = :apply_to_host_groups

  config.include Capybara::DSL
end

有人有什么建议吗?据我所知,最好的做法是每个 it 有一个 expect,所以如果我能让它工作的话,我真的很想用第一种方法。

提前致谢。

before(:all) 在评估 'it' 块之前运行该块一次。这不适用于正常的 Capybara 设置,因为 Capybara 会在每次包含 visit 'about:blank' 的测试后重置会话。如果您想为每个 it 保留一个 expect,那么您的初次访问需要在 before(:each) 块中。

话虽这么说,在应该测试页面行为(访问页面、填写字段、单击按钮等)和给定测试的功能测试中,坚持每次测试一个期望并没有多大意义会期望发生多种事情。您的测试看起来确实属于视图测试而不是功能测试。

此外,您应该使用 have_title 匹配器而不是将 eq 与 page.title

一起使用