簡體   English   中英

使用 RSpec 和 Capybara 進行 Rails 應用程序測試。 我收到錯誤 Capybara::ElementNotFound

[英]Rails app testing with RSpec and Capybara. I get Error Capybara::ElementNotFound

_customers_table.html.erb

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Phone number</th>
      <th>Description</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @customers.each do |customer| %>
      <tr>
        <td><%= customer.name %></td>
        <td><%= customer.phone_number %></td>
        <td><%= customer.description %></td>
        <td><%= link_to customer.status.humanize, toggle_status_customer_path(customer), class: "move-to-black" %></td>
        <td><%= link_to 'Show', customer %></td>
        <td><%= link_to 'Edit', edit_customer_path(customer) %></td>
        <td><%= link_to 'Destroy', customer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>


created_customer_spec.rb

require 'rails_helper'

describe "creating new customer", type: :feature do
  let(:customer) { customer = FactoryBot.create(:customer) }

  it 'should create new customer' do
    visit '/customers/new'
    fill_in 'Name', with: customer.name
    fill_in 'Phone number', with: customer.phone_number
    click_button 'Create Customer'
    expect(page).to have_content "#{customer.name}"
  end

  it 'should change customer status' do
    visit '/'
    click_on customer.status.humanize
    expect(customer).to have_status "move_to_white_list"
  end
end


第一個示例“應該創建新客戶”通過,但第二個示例“應該更改客戶狀態”出現錯誤

Capybara::ElementNotFound:
       Unable to find link or button "Move to black list"

該元素存在,您可以在圖像上看到它。 如果有人可以提供幫助,我將不勝感激。 在此處輸入圖像描述

我改變了第二個例子,現在它可以工作了。這是我的錯誤我沒有解釋清楚,“黑名單”表在不同的視圖上,當狀態改變時,它會移動到另一個頁面,所以實際上不可能在那里找到它。

    require 'rails_helper'

describe "creating new customer", type: :feature do
  let!(:customer) { customer = FactoryBot.create(:customer) }

  it 'should create new customer' do
    visit '/customers/new'
    fill_in 'Name', with: customer.name
    fill_in 'Phone number', with: customer.phone_number
    click_button 'Create Customer'
    expect(page).to have_content "#{customer.name}"
  end

  it 'should change customer status' do
    visit '/customers'
    click_on customer.status.humanize
    expect(page).to have_content "Customer #{customer.name} moved to black list"

    visit '/black_list'
    expect(customer.reload.status).to eq "move_to_white_list"
  end
end

你在這里有很多問題。 首先,您將在創建客戶實例之前進入頁面,這意味着它不會顯示在頁面上。 這是因為let懶惰地評估 - 請參閱https://relishapp.com/rspec/rspec-core/v/3-8/docs/helper-methods/let-and-let - 並且只會在第一次創建客戶時創建客戶在測試中被調用。

visit '/' # <= no customer instance exists here
click_on customer.status.humanize # <= customer instance actually created here

您可以通過使用非延遲評估版本來解決這個問題let! 這將始終創建一個客戶實例,或者在調用visit之前調用customer

其次,您的測試正在修改數據庫中的客戶實例,但永遠不會重新加載您在 memory 中的實例(因此永遠不會看到新狀態)

expect(customer.reload).to have_status "move_to_white_list"

第三,如果您使用支持異步行為的驅動程序(機架測試以外的任何驅動程序),則無法保證在方法調用返回之前由操作方法( click_on等)引起的任何副作用已經完成。 這意味着您的期望很可能會在客戶實例狀態發生變化之前被調用。 要解決這個問題,需要編寫have_status匹配器以具有重試行為(就像所有 Capybara 提供的匹配器一樣)並且在匹配器中也具有重新加載行為。 這就是為什么在系統/功能測試中驗證數據庫更改通常不是一個好主意的主要原因,而是堅持驗證 UI 中的更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM