Capybara 问题:@request 必须是 ActionDispatch::Request
我在让 Capybara 与 Rails 一起使用时遇到问题。只是测试那个所谓有趣的测试东西。好的,在所附的代码中有几个等效的测试。第一个是用Rails 自带的shoulda-context + Test::Unit 制作的。第二个测试也是使用水豚和shoulda-context 进行的。
require 'integration_test_helper'
class UsersTest < ActionDispatch::IntegrationTest
fixtures :all
context "signup" do
context "failure" do
setup do
@attr = { :name => "", :email => "", :password => "", :password_confirmation => "" }
end
should "not make a new user" do
assert_no_difference 'User.count' do
post_via_redirect "users", :user =>@attr # enviem les dades d'un nou usuari via create (POST /users)
assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari
assert_select "div#error_explanation" # comprovem que conte missatges d'error
end
end
should "not make a new user (capybara)" do
assert_no_difference 'User.count' do
visit '/signup'
fill_in 'Name', :with => @attr[:name]
fill_in 'Email', :with => @attr[:email]
fill_in 'Password', :with => @attr[:password]
fill_in 'Confirmation', :with => @attr[:password_confirmation]
click_button 'Sign Up!'
assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari
assert_select "div#error_explanation" # comprovem que conte missatges d'error
end
end
end
end
虽然第一个工作正常,但水豚会抛出此错误消息:
================================================================================
Error:
test: signup failure should not make a new user (capybara). (UsersTest):
ArgumentError: @request must be an ActionDispatch::Request
test/integration/users_test.rb:30:in `block (4 levels) in <class:UsersTest>'
test/integration/users_test.rb:23:in `block (3 levels) in <class:UsersTest>'
================================================================================
所需的 *integration_test_helper.rb* 文件是我在谷歌搜索中发现的所有假定解决方案的累加器,但对我来说不起作用。
require 'test_helper'
require 'capybara/rails'
require 'database_cleaner'
# Transactional fixtures do not work with Selenium tests, because Capybara
# uses a separate server thread, which the transactions would be hidden
# from. We hence use DatabaseCleaner to truncate our test database.
DatabaseCleaner.strategy = :truncation
class ActionDispatch::IntegrationTest
# Make the Capybara DSL available in all integration tests
include Capybara::DSL
# Stop ActiveRecord from wrapping tests in transactions
self.use_transactional_fixtures = false
teardown do
DatabaseCleaner.clean # Truncate the database
Capybara.reset_sessions! # Forget the (simulated) browser state
Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
end
end
有人有解决办法吗?我应该尝试其他集成框架,例如 webrat 吗?
我的设置是:
marcel@pua:~/Desenvolupament/Rails3Examples/ror_tutorial$ rake about
About your application's environment
Ruby version 1.9.2 (x86_64-linux)
RubyGems version 1.8.15
Rack version 1.3
Rails version 3.1.3
JavaScript Runtime therubyracer (V8)
Active Record version 3.1.3
Action Pack version 3.1.3
Active Resource version 3.1.3
Action Mailer version 3.1.3
Active Support version 3.1.3
Middleware ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000002b9bac0>, Rack::Runtime, Rack::MethodOverride, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport
Application root /mnt/dropbox/Dropbox/DESENVOLUPAMENT/Rails3Examples/ror_tutorial
Environment development
Database adapter sqlite3
Database schema version 20120127011330
也
shoulda-context (1.0.0)
capybara (1.1.2)
谢谢
I'm having problems making Capybara work with Rails. Just testing that suposedly interesting test thing. OK, in the attached code there are a couple of equivalent tests. The first one is made with shoulda-context + Test::Unit that comes with Rails. The second test is made with capybara and shoulda-context too.
require 'integration_test_helper'
class UsersTest < ActionDispatch::IntegrationTest
fixtures :all
context "signup" do
context "failure" do
setup do
@attr = { :name => "", :email => "", :password => "", :password_confirmation => "" }
end
should "not make a new user" do
assert_no_difference 'User.count' do
post_via_redirect "users", :user =>@attr # enviem les dades d'un nou usuari via create (POST /users)
assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari
assert_select "div#error_explanation" # comprovem que conte missatges d'error
end
end
should "not make a new user (capybara)" do
assert_no_difference 'User.count' do
visit '/signup'
fill_in 'Name', :with => @attr[:name]
fill_in 'Email', :with => @attr[:email]
fill_in 'Password', :with => @attr[:password]
fill_in 'Confirmation', :with => @attr[:password_confirmation]
click_button 'Sign Up!'
assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari
assert_select "div#error_explanation" # comprovem que conte missatges d'error
end
end
end
end
While the first one works OK, the capybara one throws this error message:
================================================================================
Error:
test: signup failure should not make a new user (capybara). (UsersTest):
ArgumentError: @request must be an ActionDispatch::Request
test/integration/users_test.rb:30:in `block (4 levels) in <class:UsersTest>'
test/integration/users_test.rb:23:in `block (3 levels) in <class:UsersTest>'
================================================================================
the required *integration_test_helper.rb* file is an accumulator of all suposed solutions I've found googling around and that don't work for me.
require 'test_helper'
require 'capybara/rails'
require 'database_cleaner'
# Transactional fixtures do not work with Selenium tests, because Capybara
# uses a separate server thread, which the transactions would be hidden
# from. We hence use DatabaseCleaner to truncate our test database.
DatabaseCleaner.strategy = :truncation
class ActionDispatch::IntegrationTest
# Make the Capybara DSL available in all integration tests
include Capybara::DSL
# Stop ActiveRecord from wrapping tests in transactions
self.use_transactional_fixtures = false
teardown do
DatabaseCleaner.clean # Truncate the database
Capybara.reset_sessions! # Forget the (simulated) browser state
Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
end
end
Has anybody a solution? Should I try another Integration frmawork such as webrat?
My setup is:
marcel@pua:~/Desenvolupament/Rails3Examples/ror_tutorial$ rake about
About your application's environment
Ruby version 1.9.2 (x86_64-linux)
RubyGems version 1.8.15
Rack version 1.3
Rails version 3.1.3
JavaScript Runtime therubyracer (V8)
Active Record version 3.1.3
Action Pack version 3.1.3
Active Resource version 3.1.3
Action Mailer version 3.1.3
Active Support version 3.1.3
Middleware ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000002b9bac0>, Rack::Runtime, Rack::MethodOverride, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport
Application root /mnt/dropbox/Dropbox/DESENVOLUPAMENT/Rails3Examples/ror_tutorial
Environment development
Database adapter sqlite3
Database schema version 20120127011330
Also
shoulda-context (1.0.0)
capybara (1.1.2)
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您混淆了测试类型并尝试在错误的测试类型中断言模板。您应该只在功能测试中断言模板,其中您只是直接测试控制器而不是实际模拟用户交互。
Capybara 专门用于集成测试,本质上是从最终用户与浏览器交互的角度运行测试。在这些测试中,您不应该断言模板,因为最终用户无法深入了解您的应用程序。相反,您应该测试的是某个操作是否能让您走上正确的道路。
请参阅 git 上的 Capybara 自述文件中的“DSL”部分:https://github.com/jnicklas/capybara
针对您的问题的官方说明:https://github.com/jnicklas/capybara/issues/240
You're mixing up your test types and attempting to assert a template in the wrong type of test. You should only be asserting templates within your Functional tests, where you're just directly testing a controller and not actually simulating a user interaction.
Capybara is meant specifically for Integration testing, which is essentially running tests from the viewpoint of an end-user interacting with a browser. In these tests, you should not be asserting templates because an end-user can't see that deep into your application. What you should instead be testing is that an action lands you on the correct path.
See "The DSL" section in Capybara's README on git: https://github.com/jnicklas/capybara
Official explanation for your issue: https://github.com/jnicklas/capybara/issues/240
为了我的完整性,因为我知道我会一遍又一遍地回到这个链接:
那些使用测试单元和水豚的人,这也是一个很好的入门读物:来自 techiferous。
请注意
assert page.has_content?("something")
的使用,这与
assert_equal some_path, current_path
一样可以很好地用于测试路由。它是否是最完整的,不知道,但你不需要更多。
For my completeness, because i'll know that I'll come back to this link over and over:
Those using test unit and capybara this is a good primer too: from techiferous.
Notice the use of
assert page.has_content?("something")
This is good to use as well as
assert_equal some_path, current_path
for testing routes.Is it the most complete, don't know, but you don't need much more.
感谢您的提示@Ryan。我试图弄清楚如何翻译 http:// 中的一些 RSpec 集成测试示例ruby.railstutorial.org/chapters/sign-up#sec:rspec_integration_tests 进入 Test::Unit + Capybara。原始的 RSpec 集成测试是
因此,在您回答之后,我认为原始示例不应包含
response.should render_template('users/new')
Thanks for your tips @Ryan. I was trying to figure out how to translate some RSpec Integration test examples from http://ruby.railstutorial.org/chapters/sign-up#sec:rspec_integration_tests into Test::Unit + Capybara. The original RSpec Integration test was
So, after your answer, I supose that the original example should not contain
response.should render_template('users/new')