假设我输入无效时测试新输入并测试新输入(第一次测试是在输入有效的情况下)。
例如(来自我的代码):
scenario "valid input saving" do
visit program_stream_path(@program, @stream)
click_link "#link"
fill_in "#fill_in", :with=>"1"
click_button "Next"
expect(page).to have_current_path new_students_list_stream_path(@stream)
within("#student_0") do
fill_in "Имя", :with => "Name"
fill_in "Фамилия", :with => "Surname"
fill_in "Электронная почта", :with => "randommail@mail.com"
end
print page.html
click_button "Save"
expect(page).to have_current_path program_stream_path(@program, @stream)
#...other code
end
显然,检查无效输入行为的测试会重复此部分:
scenario "invalid input leads to correct input page" do
visit program_stream_path(@program, @stream)
click_link "#link"
fill_in "#fill_in", :with=>"1"
click_button "Next"
expect(page).to have_current_path new_students_list_stream_path(@stream)
#other code
如何避免这种复制粘贴方式?
答案 0 :(得分:2)
你可以在块之前使用这种东西
feature "..." do
before :each do
visit program_stream_path(@program, @stream)
click_link "#link"
fill_in "#fill_in", :with=>"1"
click_button "Next"
expect(page).to have_current_path new_students_list_stream_path(@stream)
end
scenario "valid input saving"
#unique code for this scenario
end
scenario "invalid input leads to correct input page"
# unique code for this scenario
end
end
如果需要/需要外部特征块可以是描述或场景块,因为您可以嵌套多个级别。如果您需要在多个要素文件中使用代码,那么将其移动到您的一个规范帮助文件中的方法是有意义的。
答案 1 :(得分:0)
您可以将它放在spec文件中的方法中,然后重复使用它。
scenario "valid input saving" do
your_named_method
...
end
scenario "invalid input leads to correct input page" do
your_named_method
...
end
def your_named_method
visit program_stream_path(@program, @stream)
click_link "#link"
fill_in "#fill_in", :with=>"1"
click_button "Next"
expect(page).to have_current_path new_students_list_stream_path(@stream)
end
答案 2 :(得分:0)
使用Capybara进行测试时避免重复的一种好方法是使用Capybara Test Helpers。
RSpec.feature 'Program Stream', test_helpers: [:programs] do
before { visit program_stream_path(@program, @stream) }
scenario 'valid input saving' do
programs.click_to_add_student
programs.should.be_adding_a_student(@stream)
programs.add_student(name: 'Имя', surname: 'Фамилия', email: 'randommail@mail.com')
programs.should.have_new_student('Имя')
end
scenario 'invalid input leads to correct input page' do
programs.click_to_add_student
programs.should.be_adding_a_student(@stream)
programs.add_student(name: nil, surname: nil, email: nil)
programs.should.have_invalid_form("Name can't be blank")
end
end
除了减少代码重复之外,它还有很多more descriptive的优点,这可以使长期维护测试变得更加容易。
class ProgramsTestHelper < Capybara::TestHelper
# Actions: Encapsulate complex actions to provide a cleaner interface.
def click_to_add_student
click_link '#link'
fill_in '#fill_in', with: '1')
click_button "Next"
end
def add_student(name:, surname:, email:)
fill_in 'Имя', with: name
fill_in 'Фамилия', with: surname
fill_in 'Электронная почта', with: email
click_button 'Save'
end
# Assertions: Allow to check on element properties while keeping it DRY.
def be_adding_a_student(stream)
have_current_path urls.new_students_list_stream_path(stream)
end
def have_new_student(name)
have_content(name)
end
def have_invalid_form(message)
have('form', text: message)
end
end
请记住,您可以选择将click_to_add_student
与add_student
组合在一起,在帮助程序方法中运行断言。全部归结为how much granularity you need in tests。
Passing blocks to methods也是自定义互动或结果的好方法。