如何让我的 RSpec 相互独立地描述块 运行?

How to make my RSpec describe blocks run independently of one another?

在我的仪表板页面上,我有一个“指标”部分,其中显示了用户拥有的目标数量。我不会为没有目标的用户显示此部分。当用户创建目标并在重定向后,指标部分将出现。

在下面的 RSpec 测试中,当 RSpec 随机运行第一个 describe 时,测试通过,因为它没有找到 Metrics 部分。然而,当 RSpec 首先运行第二个 describe 块时,第一个 describe 块失败,因为此时重定向已经发生并且 Metrics 部分已经出现。

如何确保每个块单独运行并通过?

describe "Dashboard Pages", :type => :request do

  subject { page }
  let(:user) { FactoryGirl.create(:user) }

  before(:each) do 
    sign_in user
  end  

  describe "After user signs in - No Goals added yet" do

    it { is_expected.to have_title(full_title('Dashboard')) }
    it { is_expected.to have_content('Signed in successfully')}

    it "should not show the metrics section" do
      expect(page).to_not have_css("div#metrics")
    end

  end

  #
  #Notice that this runs using the SELENIUM WebDriver
  #
  describe "After user signs in - Add a new Goal" do

    it "should display the correct metrics in the dashboard", js: true do

      click_link "Create Goal"      
      fill_in "Goal Name", :with=> "Goal - 1" 
      fill_in "Type a short text describing this goal:", :with => "A random goal!"
      click_button "Save Goal"
    end  

  end

end

我认为您的问题是 click_button "Save Goal" 发送的请求在该测试完成后到达服务器。 Capybara 的 Javascript 驱动程序是异步的,不会等待它们发送到浏览器的命令完成。

让 Capybara 等待的通常方法是期望页面的某些内容在您要等待的命令完成时为真。无论如何,这在这里是个好主意,因为上次测试实际上并不期望指标像它所说的那样显示。所以期望它们是:

it "should display the correct metrics in the dashboard", js: true do
  click_link "Create Goal"      
  fill_in "Goal Name", :with=> "Goal - 1" 
  fill_in "Type a short text describing this goal:", :with => "A random goal!"
  click_button "Save Goal"
  expect(page).to have_css("div#metrics")
end

另请注意,当前 RSpec 和 Capybara 不允许您在请求规范中使用 Capybara。除非您出于其他原因依赖旧版本,否则我建议升级到当前的 RSpec 和 Capybara,并将您的请求规范转换为功能规范。