用户在测试过程中断开连接

发布于 2025-01-29 02:59:51 字数 1579 浏览 3 评论 0原文

我在Ruby上使用Rauds应用程序,该应用程序在其部署过程中进行了许多测试(〜3000) 我们使用Capybara和Selenium进行功能测试。 我们最近将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%的身份验证测试中随机发生。

我怀疑Capybara Cookie的问题,但我不知道该如何解决。

I work on a Ruby on Rails app that has many test in its deployment process (~3000)
We use capybara and selenium for feature tests.
We recently migrated CI from Heroku CI to CircleCi.
We run 10 docker instances to run our test suite.

For many feature tests, we use this block of code to sign in admin users:

def admin_signs_in
  admin_user = FactoryBot.create(:admin_user, :for_signin)
  sign_in admin_user
  return admin_user
end

But sometimes, randomly, one test doesn't pass because users get disconnected and cannot access to the page needed for the test.

An example of failing test:
require '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

We tried to use rspec-retry gem to try those tests several times, but when it fails once, it fails for all retries.

It can happen to any test in our suite, I'd say it happens in 0.1% of authenticated tests, randomly.

I suspect a problem with Capybara cookies, but I don't know how to solve this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花想c 2025-02-05 02:59:51

多亏了托马斯·沃尔波尔(Thomas Walpole),我终于找到了这个问题。
首先,显然是从测试运行中获取日志。

我设法将硒驱动程序日志保存在使用我的配置中的测试失败:

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

我想到问题可能是由于_Session_ID cookie 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",

NB:我们在撰写此帖子时在2022年。 Selenium Chrome意识到这一点,所以我的饼干立即到期。

我知道我们使用时间表将当前时间设置为某些日期相关测试,因此我搜索了不良的时间表使用情况。

我发现这条线

before { Timecop.travel(Time.parse("2021-01-05")) }

从未发布。
我将其更改为:

before { Timecop.freeze(Time.parse("2021-01-05")) }
after  { Timecop.return }

所以我的问题是我的测试服务器和测试浏览器有不同的时间。

Thanks to Thomas Walpole, I finally found the issue.
First thing is obviously to get logs from test runs.

I managed to save Selenium driver logs for failing tests using this in my config:

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

I had in mind that the problem was probably due to the _session_id cookie that Rails use to store user session.

So in my huge 2M logs file I searched for this and found this line

"Set-Cookie": "visitor_uuid=1234567890987654321; path=/; SameSite=None\n_session_id=1234567890987654321azertyu; path=/; expires=Sun, 04 Apr 2021 22:00:01 GMT; HttpOnly",

NB: We are in 2022 at the time I'm writing this post. And Selenium chrome is aware of that, so my cookie immediately expires.

I know we use Timecop to set current time for some date related tests, so I searched for a bad Timecop usage.

I found this line

before { Timecop.travel(Time.parse("2021-01-05")) }

Which is never released.
I changed it to :

before { Timecop.freeze(Time.parse("2021-01-05")) }
after  { Timecop.return }

So my issue was that my test server and test browser had a different time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文