您如何正确测试硒纸刮板?

时间:2020-03-30 22:18:16

标签: ruby selenium rspec sinatra webmock

我正在写一个使用硒来导航和登录某个网站的刮板;搜索最新数据,然后将其存储到数据库中。我正在使用selenium-webdriver来浏览网站,现在我正在尝试为最重要的边缘情况编写测试。

我下载了HTML并建立了一个伪造的Sinatra网站,该网站模仿了原始网站的行为,以便我可以测试我的代码。但是,我必须在独立于我的代码的环境中单独运行puma服务器。

我需要能够在相同的环境中模拟所有内容,以便可以更好地控制应用程序的行为。我想我可以采取与水豚队的球员相同的方法,但是我不知道如何开始。

我创建了一个简短的模拟类,它可以运行,但是只要puma启动,RSpec就立即停止,等待puma停止执行。

我可以采用哪种最佳方法来正确地测试此刮板,是否已经存在并且可以使用的技术?

我的刮板的工作原理与本教程中所述的相同:

https://dev.to/mknycha/serverless-web-scraper-in-ruby-tutorial-50hg

像这样启动rspec时,我试图通过启动模拟网站来使其工作:

require 'webmock'
require 'puma'
require 'puma/events'
require 'spec/support/fake_website'
require 'rack/handler/puma'
include WebMock::API

WebMock.reset!

def enable_external_connections!
  WebMock.allow_net_connect!
end

def disable_external_connections!
  WebMock.disable_net_connect!(allow_localhost: true, allow: ['app.local'])
end

def stub_net_connections!(options = {})
  registry = {
    "fake_website.com" => { /fake_website.com/ => proc { FakeWebsite } }
  }

  if !options[:only].to_a.empty?
    [options[:only]].flatten.each do |key|
      WebMock::API.stub_request(:any, registry[key].keys.first).to_rack(registry[key].values.first.call)
    end

    enable_external_connections!

  elsif !options[:except].to_a.empty?
    (registry.keys - [options[:except]].flatten).flatten.each do |key|
      WebMock::API.stub_request(:any, registry[key].keys.first).to_rack(registry[key].values.first.call)
    end

    enable_external_connections!

  else
    registry.keys.flatten.each do |key|
      WebMock::API.stub_request(:any, registry[key].keys.first).to_rack(registry[key].values.first.call)
    end

    disable_external_connections!
  end
end

def run_puma(example)
  options = { Host: '127.0.0.1', Port: '80', Threads: '0:4', workers: 1, daemon: true, Verbose: true }

  conf = Rack::Handler::Puma.config(FakeWebsite, options)
  events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
  puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION)

  events.log 'App starting Puma...'
  events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
  events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"

  Puma::Server.new(FakeWebsite, ::Puma::Events.stdio, conf.options).tap do |s|
    s.binder.parse conf.options[:binds], s.events
    s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
  end.run.join
end

# Disable all external requests by default.
disable_external_connections!

RSpec.configure do |config|

  # Disable external connections and stub all external services
  #
  config.before(:each) do |example|
    stub_net_connections!
    if example.metadata[:external_connections] == true
      enable_external_connections!

    elsif example.metadata[:external_connections] == false
      run_puma(example)
      disable_external_connections!
    end
  end

  config.after(:each) do |example|
  end

end

但是,此功能运行后,由于服务器已启动,测试将立即停止:

def run_puma(example)
  options = { Host: '127.0.0.1', Port: '80', Threads: '0:4', workers: 1, daemon: true, Verbose: true }

  conf = Rack::Handler::Puma.config(FakeWebsite, options)
  events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
  puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION)

  events.log 'Chimera starting Puma...'
  events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
  events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"

  Puma::Server.new(FakeWebsite, ::Puma::Events.stdio, conf.options).tap do |s|
    s.binder.parse conf.options[:binds], s.events
    s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
  end.run.join
end

这些行使测试停止:

Puma::Server.new(FakeWebsite, ::Puma::Events.stdio, conf.options).tap do |s|
  s.binder.parse conf.options[:binds], s.events
  s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
end.run.join

还有另一种方法可以实现这一目标吗?有没有工具可以测试这种类型的应用程序?

0 个答案:

没有答案