我正在测试使用Clearance身份验证gem的密码重置流程,但是我不知道如何编写一个在运行整个测试套件时通过的测试。当我单独运行该测试时,该测试通过,但在运行整个测试套件时,该测试失败并给出以下错误消息:
Capybara::ExpectationNotMet: expected "/users/467591525/password/edit?token=8fd60112cf461061eb405632f35e08a3830f661c" to equal "/users/467591525/password/edit"
我首先尝试将其作为系统测试来进行,而我在这里进行了其他所有这样的测试。那是在test/system/user_password_reset_test.rb
中,并且它是从ApplicationSystemTestCase
继承为class UserPasswordResetTest < ApplicationSystemTestCase
的。
但是当我单独运行该测试作为系统测试时,会收到相同的错误消息。
如果我使用class PasswordResetTest < ActionDispatch::IntegrationTest
将其切换为集成测试,则在单独运行时该测试会通过,但在运行整个测试套件时会出现相同的Capybara::ExpectationNotMet
错误。
这是完整的测试:
require 'application_system_test_case'
class PasswordResetTest < ActionDispatch::IntegrationTest
def setup
clear_emails
@user = users(:lee)
end
test 'User can reset their password' do
perform_enqueued_jobs do
visit sign_in_path
assert_current_path sign_in_path
click_link 'Forgot Password'
assert_current_path new_password_path
assert_title 'Password reset | Flagship'
assert_selector 'h1', text: 'Reset your password'
fill_in('Email', with: @user.email)
click_button 'Reset password'
assert_current_path passwords_path
assert_selector 'h1', text: 'Your password reset email is on the way.'
end
sleep 10
open_email(@user.email)
current_email.click_link 'Change my password'
assert_current_path(edit_user_password_path(@user, token: @user.confirmation_token))
assert_title 'Change your password | Flagship'
assert_selector 'h1', text: 'Change your password'
fill_in('Choose password', with: 'New_Password')
click_button 'Save this password'
assert_current_path(dashboard_path)
end
end
我已经很难解决这个问题了,无法弄清楚我在做什么错。这是我的test/application_system_test_case.rb
:
需要“ test_helper”
# System tests
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
include SignInHelper
end
还有我的test/test_helper.rb
:
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require 'minitest/reporters'
Minitest::Reporters.use!
# Helpers used in tests
module SignInHelper
def sign_in_as_user_without_account
@user_without_account = users(:user_without_account)
visit root_path(as: @user_without_account)
end
def sign_in_as_account_owner
@account_owner = users(:lee)
visit root_path(as: @account_owner)
end
end
# Model tests
class ActiveSupport::TestCase
parallelize(workers: :number_of_processors)
fixtures :all
end
class ActionDispatch::IntegrationTest
# Controllers
require 'capybara/rails'
require 'capybara/minitest'
include Capybara::DSL
include SignInHelper
# Mailers
include ActiveJob::TestHelper
include Capybara::Email::DSL
end
我在那里配置错误了吗?
更新
正如托马斯的答案建议添加ignore_query: true
修复了测试下降的那条线。因此,我将assert_current_path(edit_user_password_path(@user, token: @user.confirmation_token))
更改为assert_current_path(edit_user_password_path(@user), ignore_query: true)
,但是现在测试在下一步失败了。
当capybara单击电子邮件中的链接时,似乎没有进入带有允许用户创建新密码的令牌的正确页面。相反,它返回带有清除Flash消息failure_when_forbidden: Please double check the URL or try submitting the form again.
的密码重置页面。
因此,似乎Capybara以某种方式无法通过重置令牌转到正确的页面。但是奇怪的是,在单独运行时通过了测试,然后在每次运行整个测试套件时都失败了。
答案 0 :(得分:4)
这应该仍然是系统测试。之后,很可能一旦用户点击了编辑密码路由,令牌就会被重置,因此只能使用一次。这可能会使您的比较失败。但是,您实际上并不需要确认令牌是路由的一部分,因为如果令牌验证失败,您将无法进入“编辑密码”页面,而其余测试也将失败。因此,而不是
assert_current_path(edit_user_password_path(@user, token: @user.confirmation_token))
你可以做
assert_current_path(edit_user_password_path(@user), ignore_query: true)