繁体   English   中英

如何在Rails中进行DRY测试并仍然使用Capybara和Warden? (使用最小测试)

[英]How can I make tests DRY in Rails and still use Capybara and Warden? (using minitest)

我的意图是为同一表格创建一些测试,在这些测试中,我需要Capybara才能完全填写表格。 尽管如此,我还是希望避免重写用于填写表格的代码。

我没有使用RSPEC! 我正在使用minitest。

我现在面临的问题是,水豚方法visit和监狱长的辅助方法login_as不能在我访问CapybaraHelper模块。

我已经看到了这个问题,所以我在test/support文件夹中创建了我的模块,但是我提到的方法仍然无法访问。 如何在Capybara中重用代码

我已经看到了这个问题,但是我想重用的代码似乎不太适合setup方法或teardown方法。 Rails:为您的单元测试预先制作一个模型实例(用于DRY)?

我也看到过帖子说该模块应该在test_helper.rb ,但是当我向该文件添加更多模块时,它会变得凌乱。

所以现在我想知道我在做什么错。 我尝试CapybaraHelper添加到CapybaraHelper但没有帮助。 实际上,它为NoMethodError: undefined method引发了错误NoMethodError: undefined method setup。

include Devise::Test::ControllerHelpers
include Warden::Test::Helpers

在测试中重用代码是否正确? 我是否缺少帮助程序模块中应包含的内容? 所有这些方法都可以在使用CapybaraHelper:Module的测试控制器中完美地工作。

这是错误消息:

NoMethodError: undefined method `login_as' for CapybaraHelper:Module

这是来自另一个使用CapybaraHelper:Module测试的错误消息。

NoMethodError: undefined method `visit' for CapybaraHelper:Module

这是我的测试:

require 'test_helper'

class TravelsControllerTest < ActionController::TestCase
  include Devise::Test::ControllerHelpers
  include Warden::Test::Helpers
  Warden.test_mode!

  test 'should accept correct fields' do
    CapybaraHelper.login
    result = CapybaraHelper.access_and_fill_travel_page
    assert_equal "/travels/success/#{Travel.last.uuid}", result[:final_path]
  end

end

这是我在test/support/capybara/capybara_helper.rb创建的帮助程序,以避免代码重复:

require 'test_helper'
require 'capybara/rails'
require 'capybara/poltergeist'

module CapybaraHelper
  def self.access_and_fill_travel_page options = {}
    options.symbolize_keys!
    set_js_driver
    visit(Rails.application.routes.url_helpers.root_path)
    initial_path = current_path
    #Fields
    fill_in('origin', with: options[:origin] || 'Guarulhos')
    fill_autocomplete('origin', with: options[:origin] || 'Guarulhos')
    fill_in('destination', with: options[:destination] || 'Seul')
    fill_autocomplete('destination', with: options[:destination] || 'Seul')
    fill_in('date_from', with: options[:date_from] || Date.today+10)
    fill_in('date_to', with: options[:date_to] || Date.today+26)
    fill_in('adults', with: options[:adults] || 1)
    fill_in('children', with: options[:children] || 0)
    fill_in('babies', with: options[:babies] || 0)
    find('#travel-submit').click()
    final_path = current_path
    return {initial_path: initial_path, final_path: final_path}
  end

  def self.fill_autocomplete(field, options = {})
    page.execute_script %Q{ el = $('input[name=#{field}]').get(0) }
    page.execute_script %Q{ $(el).trigger('focus') }
    page.execute_script %Q{ $(el).trigger('keydown') }
    page.all('.ui-menu-item', minimum: 1)
    page.execute_script %Q{ item = $('.ui-menu-item').get(0) }
    page.execute_script %Q{ $(item).trigger('mouseenter').click() }
  end

  def self.set_js_driver
    Capybara.javascript_driver = :poltergeist
    Capybara.current_driver = Capybara.javascript_driver
  end

  def self.login
    user = FactoryGirl.create(:user)
    login_as(user, :scope => :user)
  end

end

您应该将ActionDispatch::IntegrationTest而不是ActionController::TestCase用作使用水豚进行测试的父类。 ActionController::TestCase模拟了请求阶段和Rails的大部分内容。 在Rails 5中已贬值。

不应在测试帮助程序模块上调用方法,而应将它们混合到测试类中。

class TravelsIntegrationTest < ActionDispatch::IntegrationTest
  include Devise::Test::ControllerHelpers
  include Warden::Test::Helpers
  include CapybaraHelper 
  Warden.test_mode!

  test 'should accept correct fields' do
    login
    # ...
  end
end

module CapybaraHelper
  def login(user = FactoryGirl.create(:user))
    login_as(user, scope: :user)
  end
end

除此之外,您还缺乏代码组织功能-设置Warden.test_mode!类的设置Warden.test_mode! 应该在test_helper.rb完成,不要在所有测试中重复进行。 也不要将所有步骤定义都放入一个文件中。 例如,您可以将它们放在/test/support/中。

module SessionHelper
  def login(user = FactoryGirl.create(:user))
    login_as(user, :scope => :user)
  end
end

module TravelHelper
  def access_and_fill_travel_page
    # ...
  end
end

如果您真的想保持干燥,请使用继承来设置测试类:

class BaseIntegrationTest < ActionDispatch::IntegrationTest
  include Devise::Test::ControllerHelpers
  include Warden::Test::Helpers
  include SessionHelper 
end

class TravelsIntegrationTest < BaseIntegrationTest
  test 'should accept correct fields' do
    login
    # ...
  end
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM