Как протестировать приложение ruby, использующее chanize

Я написал небольшую программу, которая использует Mechanize для перемещения по сайту.

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

Вот небольшой пример, предположим, что цель моего кода состояла в том, чтобы вытащить ссылки с главной страницы Google, поэтому я пишу тест, чтобы убедиться, что первая ссылка, которую находит мой код, имеет текст «Изображения». Я мог бы написать что-то вроде этого:

require 'rubygems'
require 'mechanize'
require 'test/unit'

def my_code_to_find_links
  google = WWW::Mechanize.new.get('http://www.google.com')
  # ...
  # some code to figure out which liks it wants
  # ...
  google.links
end

class TestGoogle < Test::Unit::TestCase
  def test_first_link_is_images
    assert_equal 'Images' , my_code_to_find_links.first.text
  end
end

Как мне смоделировать google.com, чтобы я мог протестировать my_code_to_find_links без всех накладных расходов, связанных с фактически доступом в Интернет?

спасибо - Джош


person Joshua Cheek    schedule 28.01.2010    source источник


Ответы (3)


Используйте Fakeweb, чтобы заглушить интернет-ответы.

В примере с Google сначала перейдите на веб-сайт и сохраните HTML-код нужной страницы. В этом случае предположим, что вы сохранили www.google.com через браузер или curl. Добавьте гем Fakeweb в ваш файл test.rb.

Тогда ваш код

stream = File.read("saved_google_page.html")
FakeWeb.register_uri(:get, 
    "http://www.google.com", 
    :body => stream, 
    :content_type => "text/html")

Когда вы выполняете свой стандартный вызов Mechanize

agent = Mechanize.New
page = agent.get("http://www.google.com/")

Fakeweb вернет страницу, которую вы сохранили, с заголовками content_type, установленными таким образом, что Mechanize будет считать, что она успешно подключилась к Интернету. Убедитесь, что установлен заголовок content_type, поскольку в противном случае Mechanize обрабатывает ответ как Mechanize::File, а не как Mechanize::Page. Вы можете проверить, что он полностью работает, запустив тесты на своем компьютере с отключенным сетевым подключением.

p.s. Я отвечаю на этот вопрос через 6 месяцев после того, как вопрос был задан, так как это лучший результат в Google, но на него нет ответа. Я только что потратил 30 минут, чтобы понять это сам, и подумал, что поделюсь решением.

person rhh    schedule 21.07.2010
comment
Спасибо, это сработало для меня. Вот решение, показывающее рабочий пример: github.com/JoshCheek/ Play/tree/master/mocking-the-internet - person Joshua Cheek; 21.07.2010

Если вы пишете модульные тесты, то вы смотрите не на тот конец палки, вам не нужно издеваться над google.com, но вы должны имитировать/заглушить объект Mechanize, т.е. создается объект механизма, для объекта вызывается метод get с параметром http://www.google.com . И да, вам нужно протестировать операцию, которую вы выполняете, на результате, который вы получите, посетив страницу, что вы можете легко сделать, заглушив ответ, а затем выполнив весь тест. Например, если вы используете мокко, то

mechanize = stub('WWW::Mechanize')
WWW::Mechanize.stubs(:new).returns(mechanize)
mechanize.stubs(:get).with('http://www.google.com').returns('What ever out put you are expecting so that you can test')

Я не думаю, что вам действительно нужно проверять, идет ли ваш запрос на google.com или нет, потому что это уже было протестировано в драгоценном камне Mechanize.

С другой стороны, если вы выполняете интеграционные/огуречные тесты, вы можете использовать Sinatra для подделки сайта. Sinatra позволяет очень легко написать одностраничный скрипт и запустить его как веб-сайт.

Редактировать:

Если вы не используете мокко, вам необходимо установить его и использовать в своих тестах.

sudo gem install mocha

И в ваших тестах

require 'rubygems'
require 'mocha'
person nas    schedule 28.01.2010
comment
Честно говоря, я думаю, что это вопрос мнения. Stubbbing Mechanize был бы болезненным процессом по сравнению с чем-то вроде FakeWeb, учитывая сложность объектов результата. Скорее всего, вы получите очень хрупкие/требовательные к обслуживанию тесты, которые сильно привязаны к точной реализации, заглушив ее. Хотя в целом я согласен с тем, что вам не следует тестировать внешние зависимости, я думаю, что это исключение из этого правила. - person Michael Wasser; 07.08.2012

Если вы пишете функциональные тесты и сервер не должен быть чем-то вычурным, вы можете написать небольшой HTTP-сервер, который работает только для теста; тестовый код настраивает тестируемый код для связи с небольшим HTTP-сервером на локальном хосте:.

Я рекомендую WEBRick. Установить HTTP-сервер совсем несложно.

person Wayne Conrad    schedule 28.01.2010