用户在测试运行期间断开连接
Users get disconnected during test runs
我在 Rails 上的 Ruby 应用程序上工作,该应用程序在其部署过程中进行了许多测试 (~3000)
我们使用水豚和硒进行功能测试。
我们最近将 CI 从 Heroku CI 迁移到了 CircleCi。
我们 运行 10 docker 个实例到 运行 我们的测试套件。
对于许多功能测试,我们使用此代码块登录管理员用户:
def admin_signs_in
admin_user = FactoryBot.create(:admin_user, :for_signin)
sign_in admin_user
return admin_user
end
但有时,随机地,一项测试未通过,因为用户断开连接并且无法访问测试所需的页面。
测试失败示例:
需要 'rails_helper'
RSpec.describe "Admin sets client budget to project", js: true do
let(:client) { create(:client) }
let(:project) { create(:project, client: client) }
let(:timeslots_proposal) { create(:timeslots_proposal_with_client, project: project) }
before do
admin_signs_in
# this path needs an authenticated user
visit advanced_admin_timeslots_proposal_path(timeslots_proposal)
within "#client-budget" do
find(".fa-pen").click
end
end
describe "negative amount" do
before do
within "#some_container" do
# this block doesn't fail, meaning that at this point, user is authenticated
expect(find("#some_field")["placeholder"]).to eq "Enter amount"
fill_in "some_field", with: "-235.99"
find('.btn-primary').click
end
end
it "raises an error" do
# this fails, logs indicate that user is redirected to signin page
expect(page).to have_content "Amount must be positive"
end
end
end
我们尝试使用 rspec-retry
gem 多次尝试这些测试,但是当它失败一次时,所有重试都失败了。
它可能发生在我们套件中的任何测试中,我想说它随机发生在 0.1% 的经过身份验证的测试中。
我怀疑水豚饼干有问题,但我不知道如何解决。
感谢 Thomas Walpole,我终于找到了问题所在。
首先显然是从测试运行中获取日志。
我设法在我的配置中使用它保存了失败测试的 Selenium 驱动程序日志:
config.after(:each) do |example|
if example.metadata[:js] && example.exception
File.write("#{path}/driver_logs.txt", Capybara.page.driver.browser.manage.logs.get(:driver).map(&:to_s).join("\n"))
end
end
我记得这个问题可能是由于 Rails 用来存储用户会话的 _session_id
cookie。
所以在我巨大的 2M 日志文件中我搜索了这个并找到了这一行
"Set-Cookie": "visitor_uuid=1234567890987654321; path=/; SameSite=None\n_session_id=1234567890987654321azertyu; path=/; expires=Sun, 04 Apr 2021 22:00:01 GMT; HttpOnly",
注意:我写这篇文章时是 2022 年 post。 Selenium chrome 知道这一点,所以我的 cookie 立即过期。
我知道我们使用 Timecop 为一些与日期相关的测试设置当前时间,所以我搜索了一个错误的 Timecop 用法。
我找到了这条线
before { Timecop.travel(Time.parse("2021-01-05")) }
永远不会发布。
我将其更改为:
before { Timecop.freeze(Time.parse("2021-01-05")) }
after { Timecop.return }
所以我的问题是我的测试服务器和测试浏览器的时间不同。
我在 Rails 上的 Ruby 应用程序上工作,该应用程序在其部署过程中进行了许多测试 (~3000) 我们使用水豚和硒进行功能测试。 我们最近将 CI 从 Heroku CI 迁移到了 CircleCi。 我们 运行 10 docker 个实例到 运行 我们的测试套件。
对于许多功能测试,我们使用此代码块登录管理员用户:
def admin_signs_in
admin_user = FactoryBot.create(:admin_user, :for_signin)
sign_in admin_user
return admin_user
end
但有时,随机地,一项测试未通过,因为用户断开连接并且无法访问测试所需的页面。
测试失败示例: 需要 'rails_helper'
RSpec.describe "Admin sets client budget to project", js: true do
let(:client) { create(:client) }
let(:project) { create(:project, client: client) }
let(:timeslots_proposal) { create(:timeslots_proposal_with_client, project: project) }
before do
admin_signs_in
# this path needs an authenticated user
visit advanced_admin_timeslots_proposal_path(timeslots_proposal)
within "#client-budget" do
find(".fa-pen").click
end
end
describe "negative amount" do
before do
within "#some_container" do
# this block doesn't fail, meaning that at this point, user is authenticated
expect(find("#some_field")["placeholder"]).to eq "Enter amount"
fill_in "some_field", with: "-235.99"
find('.btn-primary').click
end
end
it "raises an error" do
# this fails, logs indicate that user is redirected to signin page
expect(page).to have_content "Amount must be positive"
end
end
end
我们尝试使用 rspec-retry
gem 多次尝试这些测试,但是当它失败一次时,所有重试都失败了。
它可能发生在我们套件中的任何测试中,我想说它随机发生在 0.1% 的经过身份验证的测试中。
我怀疑水豚饼干有问题,但我不知道如何解决。
感谢 Thomas Walpole,我终于找到了问题所在。 首先显然是从测试运行中获取日志。
我设法在我的配置中使用它保存了失败测试的 Selenium 驱动程序日志:
config.after(:each) do |example|
if example.metadata[:js] && example.exception
File.write("#{path}/driver_logs.txt", Capybara.page.driver.browser.manage.logs.get(:driver).map(&:to_s).join("\n"))
end
end
我记得这个问题可能是由于 Rails 用来存储用户会话的 _session_id
cookie。
所以在我巨大的 2M 日志文件中我搜索了这个并找到了这一行
"Set-Cookie": "visitor_uuid=1234567890987654321; path=/; SameSite=None\n_session_id=1234567890987654321azertyu; path=/; expires=Sun, 04 Apr 2021 22:00:01 GMT; HttpOnly",
注意:我写这篇文章时是 2022 年 post。 Selenium chrome 知道这一点,所以我的 cookie 立即过期。
我知道我们使用 Timecop 为一些与日期相关的测试设置当前时间,所以我搜索了一个错误的 Timecop 用法。
我找到了这条线
before { Timecop.travel(Time.parse("2021-01-05")) }
永远不会发布。 我将其更改为:
before { Timecop.freeze(Time.parse("2021-01-05")) }
after { Timecop.return }
所以我的问题是我的测试服务器和测试浏览器的时间不同。