You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions执行失败:忽略本地主机设置未生效问题排查

问题:GitHub Actions中运行RSpec测试时VCR的ignore_localhost设置未生效

错误信息

Run bundle exec rspec --tag type:feature
  
Run options: include {:type="feature"}
Capybara starting Puma...
* Version 4.3.12 , codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:38995
......................F

Failures:

  1) Log In can log into the application 
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit new_user_session_path

          VCR::Errors::UnhandledHTTPRequestError:


            ================================================================================
            An HTTP request has been made that VCR does not know how to handle:
              GET https://chromedriver.storage.googleapis.com/LATEST_RELEASE_106.0.5249

            There is currently no cassette in use. There are a few ways
            you can configure VCR to handle this request:

              * If you're surprised VCR is raising this error
                and want insight about how VCR attempted to handle the request,
                you can use the debug_logger configuration option to log more details [1].
              * If you want VCR to record this request and play it back during future test
                runs, you should wrap your test (or this portion of your test) in a
                `VCR.use_cassette` block [2].
              * If you only want VCR to handle requests made while a cassette is in use,
                configure `allow_http_connections_when_no_cassette = true`. VCR will
                ignore this request since it is made when there is no cassette [3].
              * If you want VCR to ignore this request (and others like it), you can
                set an `ignore_request` callback [4].

            [1] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/debug-logging
            [2] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/getting-started
            [3] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/allow-http-connections-when-no-cassette
            [4] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/ignore-request
            ================================================================================
          # ./spec/features/login_spec.rb:9:in `block (2 levels) in <top (required)>'
          # ./spec/rails_helper.rb:69:in `block (2 levels) in <top (required)>'
          # ./spec/support/configs/config_vcr.rb:38:in `block (2 levels) in <top (required)>'

     1.2) Failure/Error: example.run

          VCR::Errors::UnhandledHTTPRequestError:


            ================================================================================
            An HTTP request has been made that VCR does not know how to handle:
              GET https://chromedriver.storage.googleapis.com/LATEST_RELEASE_106.0.5249

            There is currently no cassette in use. There are a few ways
            you can configure VCR to handle this request:

              * If you're surprised VCR is raising this error
                and want insight about how VCR attempted to handle the request,
                you can use the debug_logger configuration option to log more details [1].
              * If you want VCR to record this request and play it back during future test
                runs, you should wrap your test (or this portion of your test) in a
                `VCR.use_cassette` block [2].
              * If you only want VCR to handle requests made while a cassette is in use,
                configure `allow_http_connections_when_no_cassette = true`. VCR will
                ignore this request since it is made when there is no cassette [3].
              * If you want VCR to ignore this request (and others like it), you can
                set an `ignore_request` callback [4].

            [1] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/debug-logging
            [2] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/getting-started
            [3] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/allow-http-connections-when-no-cassette
            [4] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/ignore-request
            ================================================================================
          # ./spec/rails_helper.rb:69:in `block (2 levels) in <top (required)>'
          # ./spec/support/configs/config_vcr.rb:38:in `block (2 levels) in <top (required)>'

Finished in 1.36 seconds (files took 1.62 seconds to load)
23 examples, 1 failure

Failed examples:

rspec ./spec/features/login_spec.rb:17 # Log In can log into the application 

Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected
Coverage report generated for RSpec to /home/runner/work/ami-experience/ami-experience/tmp/coverage. 213 / 327 LOC (65.14%) covered.
Error: Process completed with exit code 1.

测试用例代码

# frozen_string_literal: true

require('rails_helper')

RSpec.describe 'Log In', type: :feature do
  let(:user) { create(:admin_user) }

  before do
    visit new_user_session_path
    expect(page).to have_button('Access')
    fill_in 'user_email', with: user.email, wait: 10
    fill_in 'user_password', with: user.password, wait: 10
    click_button 'Access'
  end

  context 'can log into the application' do
    it { expect(page).to have_content('Success!') }
  end
end

当前VCR配置

# frozen_string_literal: true

VCR.configure do |c|
  c.ignore_localhost = true
  c.cassette_library_dir = 'spec/fixtures/vcr'
  c.hook_into(:webmock)
  c.default_cassette_options = { record: :new_episodes }
  c.allow_http_connections_when_no_cassette = false
end

解决方案

核心原因

报错的请求是chromedriver自动检查最新版本的请求,目标域名是chromedriver.storage.googleapis.com,不属于localhost范围,所以ignore_localhost规则对它无效,需要单独配置忽略。

方案1:添加精准忽略规则(推荐)

修改VCR配置,增加一个ignore_request回调,匹配chromedriver的版本检查请求:

# frozen_string_literal: true

VCR.configure do |c|
  c.ignore_localhost = true
  c.cassette_library_dir = 'spec/fixtures/vcr'
  c.hook_into(:webmock)
  c.default_cassette_options = { record: :new_episodes }
  c.allow_http_connections_when_no_cassette = false
  # 忽略chromedriver的版本检查请求
  c.ignore_request do |request|
    request.uri.host == 'chromedriver.storage.googleapis.com'
  end
end

方案2:允许无cassette时的HTTP连接(谨慎使用)

如果不想逐个添加忽略规则,可以临时开启allow_http_connections_when_no_cassette = true,但这样会让所有未被VCR捕获的请求直接发送,可能降低测试的隔离性:

# frozen_string_literal: true

VCR.configure do |c|
  c.ignore_localhost = true
  c.cassette_library_dir = 'spec/fixtures/vcr'
  c.hook_into(:webmock)
  c.default_cassette_options = { record: :new_episodes }
  # 允许无cassette时发起HTTP请求
  c.allow_http_connections_when_no_cassette = true
end

额外优化(可选)

在GitHub Actions中预先安装指定版本的chromedriver,避免自动检查版本的请求。比如在workflow文件中添加:

- name: Install chromedriver
  run: |
    CHROMEDRIVER_VERSION=106.0.5249.61
    wget -N https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip -P ~/
    unzip ~/chromedriver_linux64.zip -d ~/
    rm ~/chromedriver_linux64.zip
    sudo mv -f ~/chromedriver /usr/local/bin/chromedriver
    sudo chmod +x /usr/local/bin/chromedriver

这样可以彻底避免触发版本检查请求,从根源解决问题。


内容的提问来源于stack exchange,提问作者Chris Hough

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:50:25