Ruby VCR 测试未捕获来自 sinatra 的 http 调用

问题描述 投票:0回答:1

我有一个 Sinatra 应用程序,其中包含以下调用;

  get '/test' do 
    @res = Net::HTTP.get_response(URI('http://www.iana.org/domains/reserved'))
    erb :test
  end

有景观;

<%= @res.body %>

我正在使用 Capybara + Selenium + VCR 测试此调用,它不会创建磁带。测试通过了,但由于 VCR 未正确录制,我没有获得速度优势。

#!/usr/bin/env ruby

require 'test/unit'
require 'capybara'
require 'capybara/dsl'
require 'webdrivers/chromedriver'
require 'webmock'
require 'vcr'
require 'dotenv'
require_relative "../sinatra_app.rb"

class SinatraAppTest < Test::Unit::TestCase
  include Capybara::DSL
  
  def setup
    Dotenv.load "#{__dir__}/../.env"
    Capybara.register_driver :chrome do |app|
      Capybara::Selenium::Driver.new(app, :browser => :chrome, options: chrome_options)
    end
    Capybara.default_driver = :chrome
    Capybara.default_max_wait_time = 20
    Capybara.app_host = "http://localhost:9393"

    VCR.configure do |config|
      config.cassette_library_dir = "fixtures/vcr_cassettes2"
      config.hook_into :webmock
      config.allow_http_connections_when_no_cassette = true
      config.default_cassette_options = {re_record_interval: (3600 * (24 * 30))}
      config.ignore_localhost = true
    end
  end
  

  # Settings and profile for the Chrome Browser
  # NOTE: still cannot get headless working
  def chrome_options
    opts = Selenium::WebDriver::Chrome::Options.new
    # opts.add_argument('--headless') unless ENV['UI']
    opts.add_argument('--no-sandbox')
    opts.add_argument('--disable-gpu')
    opts.add_argument('--disable-dev-shm-usage')
    opts.add_argument('--window-size=1920,1080')
    opts
  end

  def test_iana
    VCR.use_cassette("iana") do
      visit "/test"
      assert page.has_content?("Example domains")
    end
  end

  def teardown
    Capybara.reset_sessions!
    Capybara.use_default_driver
  end
end

如何捕获 Sinatra 的内部通话并通过 VCR 进行录制?

如果我在测试中放置 Net::HTTP 调用,那么我会得到正确的记录,但这不是我想要驱动测试的方式。

ruby selenium-webdriver capybara sinatra vcr
1个回答
0
投票

有两个问题需要回答,一个是你问的问题,另一个是臭名昭著的 XY 问题,这就是我要开始的地方。

如果我在测试中放置 Net::HTTP 调用,那么我会得到正确的记录,但这不是我想要驱动测试的方式。

您想要捕获响应以进行单元测试,但您还决定将其包装在集成测试中(通过使用

visit
)。最好只获取响应,然后分离出您想要测试的级别。对于集成测试,我认为 VCR 不合适,这种测试应该在没有任何模拟的情况下运行(或“绝对”最小值)。它是集成的,即它将一切整合在一起,测试中不应遗漏任何内容。因此,他们预计需要时间。他们的作用是自动化并取代您手动检查网站,它应该尽可能真实。 单元测试测试一个小单元,并且可能

应该

对事情进行模拟和重播。他们首先测试功能,因此拥有罐装数据是件好事——它的速度也是一件好事。您可能也有非模拟、非边缘情况单元测试,对于边缘情况等,显然有一个范围,但集成和单元测试位于该范围的两端。

如何捕获 Sinatra 的内部通话并通过 VCR 进行录制?

我查看了 VCR 源。它使用中间件和挂钩来获取响应。例如,这是 Typhoeus 钩子:

::Typhoeus.on_complete do |response| request = response.request restore_body_from_chunks(response, request) if request.streaming? unless VCR.library_hooks.disabled?(:typhoeus) vcr_response = vcr_response_from(response) typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request) unless request.response.mock http_interaction = VCR::HTTPInteraction.new(typed_vcr_request, vcr_response) VCR.record_http_interaction(http_interaction) end VCR.configuration.invoke_hook(:after_http_request, typed_vcr_request, vcr_response) end end

它需要一个 
response

,将其更改为

vcr_response
,然后使用它来获取
http_interaction
,然后通过
VCR.record_http_interaction(http_interaction)
进行记录。我看不到 Selenium 或 Capybara 的钩子,因此没有调用
record_http_interaction
,这可能是因为我在上面 XY 问题中概述的内容,它不合适,所以没有人写它。
当然,您可以按照 VCR 存储库中已有的 hooks 和中间件目录中的示例进行操作。我可能只是使用 Rack::Test 并使用其他人的工作,我发现这个有用的 

rack-vcr

库可以解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.