2010-01-28 12 views
17

Ho scritto un piccolo programma che utilizza Mechanize per attraversare un sito.Come testare un'applicazione ruby ​​che utilizza mechanize

Voglio scrivere test per questo, ma non voglio che acceda effettivamente al sito ogni volta che eseguo i test. Mi piacerebbe prendere in giro internet, in modo che quando si reca in qualche sito, restituisca semplicemente i risultati memorizzati.

Ecco un piccolo esempio, finta il proposito di mio codice era quello di tirare fuori i collegamenti della home page di Google, in modo da scrivere un test per assicurarsi il primo anello mio codice trova ha il testo "Immagini". Potrei scrivere qualcosa del genere:

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 

Come faccio rido google.com in modo da poter testare my_code_to_find_links senza tutto il sovraccarico di realtà l'accesso a internet?

grazie -Josh

risposta

35

Usa Fakeweb a stub le risposte internet.

Per l'esempio di Google, prima andare al sito Web e salvare l'html della pagina desiderata. In questo caso, supponiamo che tu abbia salvato www.google.com tramite il browser o l'arricciatura. Aggiungi la gemma Fakeweb al tuo test.file di rb

Poi il codice è

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

Quando fate la vostra chiamata standard di Mechanize di

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

Fakeweb tornerà pagina è stato salvato con le intestazioni content_type fissati in un modo che Mechanize sarà pensa di aver avuto accesso a Internet con successo. Assicurati che l'intestazione content_type sia impostata poiché altrimenti Mechanize considera la risposta come Mechanize :: File invece di Mechanize :: Page. È possibile verificare che funzioni completamente eseguendo test sulla macchina con la connessione di rete scollegata.

p.s. Rispondo a questo 6 mesi dopo che la domanda è stata posta poiché questo è il miglior risultato in Google ma non ha risposta. Ho appena trascorso 30 minuti a pensarci e ho pensato di condividere la soluzione.

+0

Grazie, questo ha funzionato per me. Ecco una soluzione che mostra l'esempio di lavoro: http://github.com/JoshCheek/Play/tree/master/mocking-the-internet/ –

1

se si sta scrivendo test funzionali e il server non ha bisogno di essere qualcosa di fantasia, è possibile scrivere un server HTTP poco che corre solo per il test; il codice di test configura il codice sotto test per contattare il piccolo server HTTP su localhost :.

Raccomando WEBrick. Mettere su un server HTTP è un gioco da ragazzi.

2

Se stai scrivendo test di unità, stai guardando la parte sbagliata del bastone, non è necessario prendere in giro google.com ma devi simulare/fermare l'oggetto Mechanize, es. viene creato un oggetto mechanize, viene chiamato il metodo sull'oggetto con il parametro http://www.google.com. E sì, è necessario testare l'operazione che si sta eseguendo sul risultato ottenuto visitando la pagina che si può facilmente fare con una risposta di stub e quindi facendo tutto il test. Per esempio, se si utilizza moka, quindi

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') 

Non credo che si ha realmente bisogno di verificare se la richiesta va a google.com o no, perché questo è già stato testato in Mechanize gemma.

In un'altra nota, se si stanno eseguendo test di integrazione/cetriolo, è possibile utilizzare sinatra per falsificare il sito. Sinatra rende molto facile scrivere uno script di una sola pagina ed eseguirlo come un sito web.

Edit:

Se non si utilizza moka allora avete bisogno di installarlo e richiedono nei tuoi test

sudo gem install mocha 

E in alcuni test del

require 'rubygems' 
require 'mocha' 
+3

Onestamente, penso che sia una questione di opinione. Stubing Mechanize sarebbe un processo doloroso rispetto a qualcosa come FakeWeb data la complessità degli oggetti risultato. Sarebbe più che probabile finire con test molto fragili/di alta manutenzione che sono strettamente legati all'implementazione esatta stoppiandoli. Mentre in generale sono d'accordo sul fatto che non dovresti testare le dipendenze esterne - penso che questa sia un'eccezione a questa regola. –

Problemi correlati