2017-02-08 10 views
2

Около 2 недель назад я начал изучать Ruby, я создал WebParser/Word Word, используя «open-uri» и «nokogiri». Поэтому я просто запускаю терминал с «ruby counter.rb http://test.com word» и i и с количеством совпадений этого слова, нечувствительным к регистру, поэтому я могу захватить все.Создайте справку для TDD/BDD с RSpec

SO Здесь я узнаю о RSpec, TDD, BDD и обо всем этом, и я хотел бы знать, как мой код может быть построен с использованием RSpec примеров и ожиданий. Я уже прочитал всю документацию, я строю примеры для тестирования и т. Д.

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

Вот мой код:

require 'open-uri' 
require 'nokogiri' 

class Counter 

    def initialize(url) 
     @url = url 
    end 

    def count(word, url) 
     doc = Nokogiri::HTML(open(url)) 
     doc.css('head').remove 
     doc.text.scan(/#{word}/i).size 
    end 
end 

url, word = ARGV 
puts "Found: #{Counter.new(url).count(word, url)} matches." 

Надежда кто-то может помочь мне, я действительно в рубин и нашел этот RSpec удивительные,

Спасибо, ребята, я буду учиться и ждать!

+0

Я бы предложил проверить http://www.relishapp.com/rspec/rspec-core/v/3-5/docs. Много простых примеров употребления ... – orde

ответ

3

есть команда rspec --init, которая создаст ваш шаблон.

Как только вы это сделали, откройте spec_helper.rb и потребуйте свой файл кода.

Кстати, немного странно, что ваша инициализация принимает URL-адрес и присваивает его переменной экземпляра, но метод count принимает URL-адрес в качестве аргумента.

Так предполагая, что это рефакторинг к этому:

attr_reader :url 
def initialize(url) 
    @url = url 
end 

def count(word) 
    doc = Nokogiri::HTML(open(url)) # this uses the attr_reader 
    doc.css('head').remove 
    doc.text.scan(/#{word}/i).size 
end 

Затем вы можете написать тестовый пример, как это (это не полный охват, просто пример):

describe "Counter" do 
    let(:url) { "http://some_url" } 
    let(:counter) { Counter.new url } 
    it "counts words" do 
    expect(counter.count("foo")).to(
     eq("<whatever the expected result is>") 
    ) 
    end 
end 

Использование let для set variables является необязательным. Вы также можете установить переменные внутри блока it ... do, но вам придется повторять его для каждого случая.

В дополнение к .to у вас есть .not_to, и есть много других полезных методов, кроме eq. Я рекомендую ознакомиться с документами сопоставления RSpec, чтобы ознакомиться с ними.

Следует также отметить, что этот тестовый пример будет делать HTTP-запрос, который иногда требуется, а иногда и нет. Например, если у вас много случаев и вы хотите быстро их запускать, то удаление HTTP-вызовов будет полезно. Но это означает, что вы больше не проверяете состояние URL-адреса. Что делать, если разметка меняется? Если ваш тестовый пример фактически не вызывает HTTP-вызов, вы не будете знать точно.

Тем не менее, хорошо знать, как удалить HTTP-вызов, так как базовая концепция («насмешливость» или «stubbing») имеет много применений. Что-то вроде этого:

it "counts words" do 
    mock_html = <<-HTML 
     <!doctype html> 
     <html lang='en'> 
     <head></head> 
     <body>foo</body> 
     </html> 
    HTML 
    expect(Object).to(
     receive(:open).with(any_args).at_least(1).times.and_return(mock_html) 
    ) 
    expect(counter.count("foo")).to eq(1) 
    expect(counter.count("bar")).to eq(0) 
    end 

any_args это специальный термин, который вы можете использовать, когда гася методы. Вы также можете использовать url, так как вы знаете, каков будет переданный аргумент.

Для получения дополнительной информации снова я передам вам документы RSpec, на этот раз те, которые насмехаются/стучат.

Как правило, вы хотите сосредоточиться в основном на вводе/выводе функций. Иногда вам нужно будет проверить, что вызывается другой метод (для этого вы должны использовать mock/stub), но вам, вероятно, не стоит проверять каждую строку кода.

+0

'rspec init' или' rspec --init'? –

+0

Вау, это было невероятно полезно, по-настоящему. Большое спасибо за помощь. И если я загружаю исходный код со страницы, поэтому мне не нужно делать HTTP-запрос, я хочу просто прочитать файл.html, который я скачал, как мне это сделать? поместить путь файла в переменную? – MoscrowDev