ruby-on-rails - Capybara 问题:@request 必须是 ActionDispatch::Request

标签 ruby-on-rails capybara shoulda testunit

我在使 Capybara 与 Rails 一起工作时遇到问题。只是测试那个所谓有趣的测试东西。好的,在附加的代码中有几个等效的测试。第一个是使用 Rails 附带的 shoulda-context + Test::Unit 制作的。第二个测试也是用 capybara 和 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

虽然第一个工作正常,但 capybara 会抛出此错误消息:
================================================================================
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* 文件是我在谷歌搜索中发现的所有 suposed 解决方案的累加器,但对我不起作用。
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)

谢谢

最佳答案

您正在混淆测试类型并试图在错误的测试类型中断言模板。您应该只在功能测试中断言模板,您只是直接测试 Controller 而不是实际模拟用户交互。

Capybara 专门用于集成测试,它本质上是从与浏览器交互的最终用户的角度运行测试。在这些测试中,您不应断言模板,因为最终用户无法深入了解您的应用程序。相反,您应该测试的是某个 Action 是否让您走上了正确的道路。

current_path.should == new_user_path
page.should have_selector('div#error_explanation')

请参阅 git 上 Capybara 的自述文件中的“DSL”部分:https://github.com/jnicklas/capybara

您的问题的官方解释:https://github.com/jnicklas/capybara/issues/240

关于ruby-on-rails - Capybara 问题:@request 必须是 ActionDispatch::Request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9104915/

相关文章:

ruby-on-rails - 使用 Rspec/Capybara/Selenium 与 Canvas 元素交互

ruby-on-rails - 打印 Rails 应用程序中所有测试的列表

ruby-on-rails - nginx 未在 Rails 静态 Assets 上设置过期 header

ruby-on-rails - 像github一样的Rails路由

ruby-on-rails - 用于 rails 的 Evercookie

javascript - JS 中的 URL 编码以获得有意义的 URL 和 Rails 页面缓存

ruby - 如何使用 capybara 更改文本框中的值?

css - 在 Capybara 测试中关闭动画

ruby-on-rails - 如何对任意列表使用 ensure_inclusion_of

ruby-on-rails-3 - 对 ActiveRecord 模型中包含的模块进行单元测试