2017-02-08 1 views
2

Seit ungefähr 2 Wochen habe ich angefangen Ruby zu lernen, ich habe einen WebParser/Page WordCounter mit 'open-uri' und 'nokogiri' gemacht. Also renne ich einfach das Terminal mit 'ruby counter.rb http://test.com word' und ich und up mit der Anzahl der Übereinstimmungen dieses Wortes, case insensitive, damit ich alles packen kann.Hilfe für TDD/BDD mit RSpec erstellen

SO hier bin ich über RSpec, TDD, BDD und all diese Sachen lernen, und ich würde gerne wissen, wie mein Code mit RSpec Beispielen und Erwartungen erstellt werden könnte. Ich habe bereits die ganze Dokumentation gelesen, ich baue simples Beispiele zu testen, etc.

Ich würde gerne wissen, ob es jemanden gibt, der meinen Code in RSpec Beispiele und Erwartungen bauen könnte, damit ich studieren kann, was Sie haben getan und wie du es gemacht hast.

Hier ist mein Code:

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." 

Hoffnung mir jemand helfen könnte, ich bin wirklich in Rubin und fanden diese RSpec erstaunlich,

Danke Jungs, werde ich studieren und warten!

+0

Ich würde vorschlagen, http://www.relishapp.com/rspec/rspec-core/v/3-5/docs auschecken. Viele einfach zu konsumierende Beispiele ... – orde

Antwort

3

Es gibt einen rspec --init Befehl, der Ihren Textbaustein erstellt.

Sobald Sie dies getan haben, öffnen Sie spec_helper.rb und benötigen Ihre Codedatei.

Übrigens ist es etwas seltsam, dass Ihre Initialisierung eine URL akzeptiert und sie einer Instanzvariablen zuweist, aber die Methode count eine URL als Argument verwendet.

unter der Annahme, so liegt es an dieser Refactoring:

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 

Dann können Sie einen Testfall wie folgt schreiben (dies ist nicht eine umfassende Abdeckung, nur ein Beispiel):

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 Verwendung zu Variablen setzen ist optional. Sie könnten auch die Variablen innerhalb des Blocks it ... do setzen, aber Sie müssen es für jeden Fall wiederholen.

Zusätzlich zu .to haben Sie .not_to, und es gibt viele andere hilfreiche Methoden als eq. Ich empfehle Ihnen, die RSpec-Matcher-Dokumente zu lesen, um sich mit diesen vertraut zu machen.

Es ist auch erwähnenswert, dass dieser Testfall einen HTTP-Aufruf machen wird, der manchmal gewünscht ist und manchmal nicht. Wenn Sie beispielsweise viele Fälle haben und diese schnell ausführen möchten, ist das Entfernen von HTTP-Aufrufen von Vorteil. Aber das bedeutet, dass Sie den Status der URL nicht mehr wirklich testen. Was passiert, wenn sich das Markup ändert? Wenn Ihr Testfall den HTTP-Aufruf nicht tatsächlich durchführt, werden Sie nicht sicher wissen.

Dennoch ist es gut zu wissen, wie man den HTTP-Aufruf entfernt, da das zugrundeliegende Konzept ("Mocking" oder "Stubbing") eine Menge Nutzen hat. Etwas wie folgt aus:

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 ist ein spezieller Begriff, den Sie, wenn Methoden stubbing verwenden können. Sie könnten auch url hier verwenden, da Sie wissen, was das übergebene Argument sein wird.

Für weitere Informationen, ich verweise Sie wieder auf RSpec's Dokumente, dieses Mal die über Spott/Stubbing.

Im Allgemeinen möchten Sie sich hauptsächlich auf die Eingabe/Ausgabe von Funktionen konzentrieren. Manchmal möchten Sie überprüfen, ob eine andere Methode aufgerufen wird (Sie würden dafür mock/stub verwenden), aber es wird wahrscheinlich nicht erwartet, dass Sie jede einzelne Codezeile testen.

+0

'rspec init' oder' rspec --init'? –

+0

Wow, das war unglaublich hilfreich, echt. Vielen Dank für die Hilfe. Und wenn ich den Quellcode von einer Seite herunterladen, so brauche ich keine HTTP-Anfrage, ich möchte nur die Datei.html lesen, die ich heruntergeladen habe, wie mache ich das? den Dateipfad in eine Variable schreiben? – MoscrowDev