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



受到这个问题讨论的启发,我想为我的集成测试编写一个登录方法。在我的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在他的rails教程中展示的机制。

这是我的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

你不能在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)

注意——你还应该有手动登录的测试来验证它的工作,并且在测试环境中只有中间件是非常重要的

相关内容

最新更新