Как правильно протестировать веб-скребок для селена? - PullRequest
0 голосов
/ 31 марта 2020

Я пишу скребок, который использует селен для навигации и входа на определенный сайт; поиск новейших данных, а затем сохранить их в базе данных. Я использую Selen-WebDriver для навигации по сайту, и теперь я пытаюсь написать тесты для наиболее важных крайних случаев.

Я скачал HTML и создал поддельный веб-сайт Sinatra, который имитирует поведение исходного сайта, чтобы я мог проверить свой код. Однако мне приходится запускать сервер puma отдельно в среде, не зависящей от моего кода.

Мне нужно иметь возможность макетировать все в одной и той же среде, чтобы лучше контролировать поведение приложения. Я думаю, что могу использовать тот же подход, что и ребята из Capybara, но я не знаю, как начать.

Я создал короткий класс насмешки, и он запускается, но как только Puma запускает RSpe c остановлен в ожидании остановки пумы.

Какой наилучший подход я могу предпринять, чтобы действительно проверить этот скребок правильно, есть ли какие-либо технологии, которые уже существуют и которые я могу использовать?

Мой скребок работает так же, как описано в этом уроке:

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

Я попытался заставить его работать, запустив поддельный веб-сайт при запуске rspe c, как this:

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

Есть ли другой способ добиться этого? Есть ли инструменты для тестирования приложений такого типа?

...