如何在集成测试中编写用于签署用户的快捷方式?

时间:2015-07-30 10:30:01

标签: ruby-on-rails ruby-on-rails-4 capybara integration-testing minitest

受到question中讨论的启发,我想为集成测试编写一个登录方法。在我的test_helper.rb中,我甚至找到了这样的方法,但它是在ActiveSupport::TestCase类中定义的,我的测试继承自ActionDispatch::IntegrationTest。所以我复制了方法并将它(在test_helper.rb内)放入ActionDispatch::IntegrationTest类。但它不起作用,我的测试失败了这条消息:

Capybara::ExpectationNotMet: expected "data:," to include "Study | Word Up"

它实际上从未像以前那样在浏览器中打开应用程序。

所以我的问题是,我可以在集成测试中使用这样的快捷方式,如果是,那该怎么办?

我正在使用has_secure_password的身份验证和Michael Hartl在他的Railstutorial中显示的机制。

这是我的test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'minitest/rails'
require 'minitest/rails/capybara'
require 'capybara/rails'
require 'capybara/poltergeist'

class ActiveSupport::TestCase
  ActiveRecord::Migration.check_pending!
  fixtures :all
  # Logs in a test user.
  def log_in_as(user, options = {})
    password    = options[:password]    || 'password'
    remember_me = options[:remember_me] || '1'
    if integration_test?
     post login_path, session: { email:       user.email,
                              password:    password,
                              remember_me: remember_me }
    else
      session[:user_id] = user.id
    end
  end

  private

  def integration_test?
    defined?(post_via_redirect)
  end
end

class ActionDispatch::IntegrationTest
  include Capybara::DSL

  def log_in_as(user, options = {})
    password    = options[:password]    || 'password'
    remember_me = options[:remember_me] || '1'
    if integration_test?
      post login_path, session: { email:       user.email,
                              password:    password,
                              remember_me: remember_me }
    else
      session[:user_id] = user.id
    end
  end
end

class ActiveRecord::Base  
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
   @@shared_connection || retrieve_connection
  end
end  

ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection 

Capybara.register_driver :selenium_chrome do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.current_driver = :selenium_chrome
Capybara.default_wait_time = 5 

测试本身如下:

require 'test_helper'

class StudyCapybaraTest < ActionDispatch::IntegrationTest
  def setup
    @user = users(:archer)
    @vocabs = @user.vocabs

    log_in_as @user 
    # visit login_path
    # fill_in "session_email",  with: @user.email
    # fill_in "session_password",   with: 'password'
    # click_button "session_commit"
  end
  ....

end

1 个答案:

答案 0 :(得分:0)

您不能在Capybara中使用#post方法,因为它不会被路由到驱动程序,这就是浏览器无法为您打开的原因。要在集成测试中快速登录,最简单的解决方案是在测试环境中安装后门中间件,如下所示 - https://robots.thoughtbot.com/faster-tests-sign-in-through-the-back-door 这个例子是为了清除所以你必须改变

@env[:clearance].sign_in(user)
当用户密码被验证为有效时,

执行您正在执行的操作,但除此之外它应该可以正常工作。然后你实际上不需要login_as,你可以做到

visit page_being_tested_path(as: user.id)

注意 - 您还应该有手动执行日志记录的测试以验证它是否有效,并且非常重要的是您只在测试环境中拥有该中间件