Как протестировать приложение ruby, которое использует mechanize - PullRequest
18 голосов
/ 28 января 2010

Я написал небольшую программу, которая использует 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 без лишних затрат на на самом деле доступа в интернет?

спасибо -Josh

Ответы [ 3 ]

36 голосов
/ 21 июля 2010

Используйте 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")

Когда вы делаете ваш стандартный вызов Механизировать

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 минут на то, чтобы понять это сам, и решил поделиться решением.

2 голосов
/ 28 января 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 gem.

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

Edit:

Если вы не используете mocha, вам нужно установить его и включить в свои тесты

sudo gem install mocha

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

require 'rubygems'
require 'mocha'
1 голос
/ 28 января 2010

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

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

...