[英]How can I make tests DRY in Rails and still use Capybara and Warden? (using minitest)
My intention is to create a few tests for the same form, and in these tests I need Capybara to fill the form completely. 我的意图是为同一表格创建一些测试,在这些测试中,我需要Capybara才能完全填写表格。 Still, I wanted to avoid rewriting the code for filling the form.
尽管如此,我还是希望避免重写用于填写表格的代码。
I'm not using RSPEC! 我没有使用RSPEC! I'm using minitest.
我正在使用minitest。
The problem I'm facing is that the Capybara method visit
and the Warden helper method login_as
are not accessible from my CapybaraHelper
module. 我现在面临的问题是,水豚方法
visit
和监狱长的辅助方法login_as
不能在我访问CapybaraHelper
模块。
I've seen this question, so I created my module in the test/support
folder, but the methods I mentioned still are not accessible. 我已经看到了这个问题,所以我在
test/support
文件夹中创建了我的模块,但是我提到的方法仍然无法访问。 How to reuse code in Capybara 如何在Capybara中重用代码
I've seen this question, but the code I want to reuse doesn't seem to fit well in the setup
method nor in the teardown
method. 我已经看到了这个问题,但是我想重用的代码似乎不太适合
setup
方法或teardown
方法。 Rails: Premake a model instance for your unit tests (for DRY purposes)? Rails:为您的单元测试预先制作一个模型实例(用于DRY)?
I've also seen posts saying this module should be inside test_helper.rb
, but as I add more modules to this file it will get messy. 我也看到过帖子说该模块应该在
test_helper.rb
,但是当我向该文件添加更多模块时,它会变得凌乱。
So now I'm wondering what I'm doing wrong. 所以现在我想知道我在做什么错。 I've tried adding the following lines to
CapybaraHelper
but it didn't help. 我尝试
CapybaraHelper
添加到CapybaraHelper
但没有帮助。 It actually raised the error NoMethodError: undefined method
setup' for CapybaraHelper:Module`. 实际上,它为
NoMethodError: undefined method
引发了错误NoMethodError: undefined method
setup。
include Devise::Test::ControllerHelpers
include Warden::Test::Helpers
Is it the right way to reuse code in tests? 在测试中重用代码是否正确? Am I missing something that should be included in my helper module?
我是否缺少帮助程序模块中应包含的内容? All those methods work perfectly in the test controller that is using
CapybaraHelper:Module
. 所有这些方法都可以在使用
CapybaraHelper:Module
的测试控制器中完美地工作。
Here is the error message: 这是错误消息:
NoMethodError: undefined method `login_as' for CapybaraHelper:Module
And here is an error message from another test using CapybaraHelper:Module
. 这是来自另一个使用
CapybaraHelper:Module
测试的错误消息。
NoMethodError: undefined method `visit' for CapybaraHelper:Module
Here's my test: 这是我的测试:
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
And here's the helper I created in test/support/capybara/capybara_helper.rb
to avoid code duplication: 这是我在
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
You should use ActionDispatch::IntegrationTest
and not ActionController::TestCase
as the parent class for tests using capybara. 您应该将
ActionDispatch::IntegrationTest
而不是ActionController::TestCase
用作使用水豚进行测试的父类。 ActionController::TestCase
mocks out the request phase and large parts of Rails. ActionController::TestCase
模拟了请求阶段和Rails的大部分内容。 It is depreciated in Rails 5. 在Rails 5中已贬值。
Instead of calling methods on your test helper module you should mix them into your test classes. 不应在测试帮助程序模块上调用方法,而应将它们混合到测试类中。
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
Apart from that you are lacking in code organization - setup steps like setting Warden.test_mode!
除此之外,您还缺乏代码组织功能-设置
Warden.test_mode!
类的设置Warden.test_mode!
should be done in your test_helper.rb
not repeated across your tests. 应该在
test_helper.rb
完成,不要在所有测试中重复进行。 Don't throw all your step definitions into a single file either. 也不要将所有步骤定义都放入一个文件中。 You can place them in
/test/support/
for example. 例如,您可以将它们放在
/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
And if you really want to keep it dry use inheritance to setup your test classes: 如果您真的想保持干燥,请使用继承来设置测试类:
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.