避免Rspec + Capybara

时间:2016-01-02 15:44:12

标签: ruby-on-rails rspec capybara

假设我输入无效时测试新输入并测试新输入(第一次测试是在输入有效的情况下)。

例如(来自我的代码):

 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

如何避免这种复制粘贴方式?

3 个答案:

答案 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_studentadd_student组合在一起,在帮助程序方法中运行断言。全部归结为how much granularity you need in tests

Passing blocks to methods也是自定义互动或结果的好方法。