这个失败的单选按钮功能测试是 Capybara 语法问题吗?
Is this failing radio button feature test a Capybara syntax issue?
我有一个带有布尔属性单选按钮的表单 prev_cover
,在浏览器中显示是或否,参数值为 true 或 false,并在数据库中保存为 true 或 false 作为数据类型 boolean。我正在尝试:
- a) 模型测试单选按钮选择的存在
- b) 功能测试整个报价记录的创建。
验证 prev_cover
到位后,我告诉水豚 within(".quote_prev_cover") { choose('No') }
create_quote_spec 测试失败,模型 quote.rb 测试通过。
验证 prev_cover
到位后,我告诉水豚 within(".quote_prev_cover") { choose('Yes') }
create_quote_spec 测试通过,模型 quote.rb 测试通过。
In actual manual browser testing the db record is created when either Yes or No is selected.
当我从 quote.rb 中删除 prev_cover 的存在验证时,create_quote_spec 通过并选择了 prev_cover 是或否,当然模型 quote_spec.rb 测试失败。
我看不出问题出在哪里,可能与水豚 within(".quote_prev_cover") { choose('No') }
语法有关吗? (它发现 css 元素很好)
这是new.html.erb
的表单元素
<div class='container'>
<div class='row'>
<div class='col-md-6'>
<%= simple_form_for @quote do |f| %>
<%= f.input :prev_cover, as: :radio_buttons, label: "Previous cover" %>
<%= f.submit "Get quote", class: 'btn btn-primary' %>
<% end %>
</div>
</div>
</div>
这里是quote.rb验证;
validates :prev_cover, inclusion: { in: [true, false] }
这是水豚创建的被调用 NewQuoteFrom.new 的 prev_cover
元素;
within(".quote_prev_cover") { choose('No') }
这里的测试如果选择 prev_cover 'No' 则失败,如果选择 'Yes' 则通过,create_quote_spec.rb
feature 'creating quote request' do
let(:user) { FactoryGirl.create(:user) }
let(:new_quote_form) { NewQuoteForm.new }
before do
login_as(user, :scope => :user)
end
scenario 'completing quote data' do
new_quote_form.visit_page.fill_in_with().submit
expect(page).to have_content('Quote request created')
end
这是在存在模型验证时通过的模型测试,quote_spec.rb;
context 'previous cover' do
it 'must be true or false' do
quote = Quote.new(prev_cover: nil)
quote.valid?
expect(quote.errors[:prev_cover]).not_to be_empty
end
end
测试失败消息:
1) creating quote request completing quote data
Failure/Error: expect(page).to have_content('Quote request created')
expected to find text "Quote request created" in "Toggle navigation QuoteEngine My Quotes My Account Sign out Complete the below to get a quote * GLA Previous coverYesNois not included in the list * Company name * Company number * Postcode * Industry Financial services Architect Business consultancy Lives overseasYesNo Scheme start date 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 January February March April May June July August September October November December 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Payment frequency Annually Monthly Commission level"
# ./spec/features/create_quote_spec.rb:14:in `block (2 levels) in <top (required)>'
注意错误消息中的 YesNois not included in the list
,在 Capybara 指令中使用 true 或 false 的任何变体也不起作用。
甚至指定:
<%= f.input :prev_cover, as: :radio_buttons, :collection => [['Yes', true],
['No', false]], label: "Previous cover" %>
在 new.html.erb 视图中的 simpl_form_for 仍然导致验证失败 Previous coverYesNois not included in the list
!?
甚至 within(".quote_prev_cover") { choose('quote_prev_cover_false') }
仍然失败并显示相同的 Previous coverYesNois not included in the list
。
如果被告知选择是 within(".quote_prev_cover") { choose('Yes') }
,它就会通过,就好像我还没有从 presence:
更改为 inclusion:
,而我肯定已经完成了。
来自 firefox 检查器的实际 HTML:
<div class="form-group radio_buttons optional quote_prev_cover">
<label class="control-label radio_buttons optional">Previous cover</label>
<input name="quote[prev_cover]" value="" type="hidden">
<span class="radio">
<label for="quote_prev_cover_true">
<input class="radio_buttons optional" value="true" name="quote[prev_cover]" id="quote_prev_cover_true" type="radio">Yes</label>
</span>
<span class="radio">
<label for="quote_prev_cover_false">
<input class="radio_buttons optional" readonly="readonly" value="false" name="quote[prev_cover]" id="quote_prev_cover_false" type="radio">No</label>
</span>
</div>
只有当您的陈述 "In actual manual browser testing the db record is created when either Yes or No is selected with corresponding boolean values created just fine." 不正确时,这份报告才有意义。
那是因为您正在使用 validates_presence_of
(通过验证存在:{...} 快捷方式)验证器,如果 false
是有效响应,则不能与布尔字段一起使用。来自 validates_presence_of
文档
If you want to validate the presence of a boolean field (where the
real values are true and false), you will want to use
validates_inclusion_of :field_name, in: [true, false].
This is due to the way Object#blank? handles boolean values:
false.blank? # => true.
因此,如果您从在线状态验证更改为
validates :prev_cover, inclusion: { in: [true, false] }
你的测试可能会通过。
导致此 Capybara 测试尝试创建报价记录失败的问题是它无法 select 布尔单选按钮的 No/false 值,这是由于 simple_form 错误已设置 readonly="readonly"
。有两种解决方案,在此提供 post here
1) 在 config/initializers/simple_form_bootstrap.rb 中注释掉 :vertical_radio_and_checkboxes
包装器中的 b.optional :readonly
。
2) 如下设置您的简单表单参数:
<%= f.input :prev_cover, as: :radio_buttons, collection: [['Yes', true],
['No', false]], readonly: nil %>
虽然选项 2 仍然有水豚在您 运行 测试时给您警告; Attempt to set readonly element with value: true * This will raise an exception in a future version of Capybara
感谢#ThomasWalpole 一路帮助我和 platformatec 维护者。
我有一个带有布尔属性单选按钮的表单 prev_cover
,在浏览器中显示是或否,参数值为 true 或 false,并在数据库中保存为 true 或 false 作为数据类型 boolean。我正在尝试:
- a) 模型测试单选按钮选择的存在
- b) 功能测试整个报价记录的创建。
验证 prev_cover
到位后,我告诉水豚 within(".quote_prev_cover") { choose('No') }
create_quote_spec 测试失败,模型 quote.rb 测试通过。
验证 prev_cover
到位后,我告诉水豚 within(".quote_prev_cover") { choose('Yes') }
create_quote_spec 测试通过,模型 quote.rb 测试通过。
In actual manual browser testing the db record is created when either Yes or No is selected.
当我从 quote.rb 中删除 prev_cover 的存在验证时,create_quote_spec 通过并选择了 prev_cover 是或否,当然模型 quote_spec.rb 测试失败。
我看不出问题出在哪里,可能与水豚 within(".quote_prev_cover") { choose('No') }
语法有关吗? (它发现 css 元素很好)
这是new.html.erb
的表单元素<div class='container'>
<div class='row'>
<div class='col-md-6'>
<%= simple_form_for @quote do |f| %>
<%= f.input :prev_cover, as: :radio_buttons, label: "Previous cover" %>
<%= f.submit "Get quote", class: 'btn btn-primary' %>
<% end %>
</div>
</div>
</div>
这里是quote.rb验证;
validates :prev_cover, inclusion: { in: [true, false] }
这是水豚创建的被调用 NewQuoteFrom.new 的 prev_cover
元素;
within(".quote_prev_cover") { choose('No') }
这里的测试如果选择 prev_cover 'No' 则失败,如果选择 'Yes' 则通过,create_quote_spec.rb
feature 'creating quote request' do
let(:user) { FactoryGirl.create(:user) }
let(:new_quote_form) { NewQuoteForm.new }
before do
login_as(user, :scope => :user)
end
scenario 'completing quote data' do
new_quote_form.visit_page.fill_in_with().submit
expect(page).to have_content('Quote request created')
end
这是在存在模型验证时通过的模型测试,quote_spec.rb;
context 'previous cover' do
it 'must be true or false' do
quote = Quote.new(prev_cover: nil)
quote.valid?
expect(quote.errors[:prev_cover]).not_to be_empty
end
end
测试失败消息:
1) creating quote request completing quote data
Failure/Error: expect(page).to have_content('Quote request created')
expected to find text "Quote request created" in "Toggle navigation QuoteEngine My Quotes My Account Sign out Complete the below to get a quote * GLA Previous coverYesNois not included in the list * Company name * Company number * Postcode * Industry Financial services Architect Business consultancy Lives overseasYesNo Scheme start date 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 January February March April May June July August September October November December 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Payment frequency Annually Monthly Commission level"
# ./spec/features/create_quote_spec.rb:14:in `block (2 levels) in <top (required)>'
注意错误消息中的 YesNois not included in the list
,在 Capybara 指令中使用 true 或 false 的任何变体也不起作用。
甚至指定:
<%= f.input :prev_cover, as: :radio_buttons, :collection => [['Yes', true],
['No', false]], label: "Previous cover" %>
在 new.html.erb 视图中的 simpl_form_for 仍然导致验证失败 Previous coverYesNois not included in the list
!?
甚至 within(".quote_prev_cover") { choose('quote_prev_cover_false') }
仍然失败并显示相同的 Previous coverYesNois not included in the list
。
如果被告知选择是 within(".quote_prev_cover") { choose('Yes') }
,它就会通过,就好像我还没有从 presence:
更改为 inclusion:
,而我肯定已经完成了。
来自 firefox 检查器的实际 HTML:
<div class="form-group radio_buttons optional quote_prev_cover">
<label class="control-label radio_buttons optional">Previous cover</label>
<input name="quote[prev_cover]" value="" type="hidden">
<span class="radio">
<label for="quote_prev_cover_true">
<input class="radio_buttons optional" value="true" name="quote[prev_cover]" id="quote_prev_cover_true" type="radio">Yes</label>
</span>
<span class="radio">
<label for="quote_prev_cover_false">
<input class="radio_buttons optional" readonly="readonly" value="false" name="quote[prev_cover]" id="quote_prev_cover_false" type="radio">No</label>
</span>
</div>
只有当您的陈述 "In actual manual browser testing the db record is created when either Yes or No is selected with corresponding boolean values created just fine." 不正确时,这份报告才有意义。
那是因为您正在使用 validates_presence_of
(通过验证存在:{...} 快捷方式)验证器,如果 false
是有效响应,则不能与布尔字段一起使用。来自 validates_presence_of
文档
If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, in: [true, false].
This is due to the way Object#blank? handles boolean values: false.blank? # => true.
因此,如果您从在线状态验证更改为
validates :prev_cover, inclusion: { in: [true, false] }
你的测试可能会通过。
导致此 Capybara 测试尝试创建报价记录失败的问题是它无法 select 布尔单选按钮的 No/false 值,这是由于 simple_form 错误已设置 readonly="readonly"
。有两种解决方案,在此提供 post here
1) 在 config/initializers/simple_form_bootstrap.rb 中注释掉 :vertical_radio_and_checkboxes
包装器中的 b.optional :readonly
。
2) 如下设置您的简单表单参数:
<%= f.input :prev_cover, as: :radio_buttons, collection: [['Yes', true],
['No', false]], readonly: nil %>
虽然选项 2 仍然有水豚在您 运行 测试时给您警告; Attempt to set readonly element with value: true * This will raise an exception in a future version of Capybara
感谢#ThomasWalpole 一路帮助我和 platformatec 维护者。