Non penso di doverti convincere che testare il tuo codice JavaScript è una buona idea. Ma a volte può risultare noioso testare il codice JavaScript che richiede un DOM. Ciò significa che è necessario testare il codice nel browser e non è possibile utilizzare il terminale, giusto? Sbagliato, in realtà: inserisci PhantomJS.
Cosa è esattamente PhantomJS? Bene, ecco una descrizione del sito Web di PhantomJS:
PhantomJS è un WebKit senza testa con API JavaScript.
Come sai, Webkit è il motore di layout utilizzato da Chrome, Safari e altri browser di nicchia. Quindi PhantomJS è un browser, ma un browser senza testa. Ciò significa che le pagine Web renderizzate non vengono mai effettivamente visualizzate. Questo può sembrare strano per te; quindi puoi pensarlo come un browser programmabile per il terminale. Vedremo un esempio semplice in un minuto, ma prima dobbiamo installare PhantomJS.
Installare PhantomJS è in realtà piuttosto semplice: è solo un singolo binario che si scarica e si conficca nel percorso del terminale. Nella pagina di download di PhantomJS, scegli il tuo sistema operativo e scarica il pacchetto corretto. Quindi sposta il file binario dal pacchetto scaricato in una directory all'interno del percorso del terminale (mi piace inserire questo tipo di cose ~ / Bin
).
Se sei su Mac OS X, c'è un modo più semplice per installare PhantomJS (e questo è in realtà il metodo che ho usato). Basta usare Homebrew, come questo:
brew update & brew install phantomjs
Ora dovresti avere PhantomJS installato. Puoi ricontrollare l'installazione eseguendo questo:
phantomjs --version
Sto vedendo 1.7.0; tu?
Iniziamo con un piccolo esempio.
console.log ("siamo in grado di registrare cose."); funzione add (a, b) return a + b; conslole.log ("Possiamo eseguire anche regolare JS:", add (1, 2)); phantom.exit ();
Vai avanti ed esegui questo codice inviando il seguente comando:
phantomjs simple.js
Dovresti vedere l'output dei due console.log
linee nella finestra del terminale.
Certo, questo è semplice, ma è un buon punto: PhantomJS può eseguire JavaScript proprio come un browser. Tuttavia, questo esempio non ha alcun codice specifico di PhantomJS ... beh, a parte l'ultima riga. Questa è una linea importante per ogni script PhantomJS perché esce dallo script. Questo potrebbe non avere senso qui, ma ricorda che JavaScript non viene sempre eseguito in modo lineare. Ad esempio, potresti voler mettere il Uscita()
chiama una funzione di callback.
Diamo un'occhiata ad un esempio più complesso.
Utilizzando l'API PhantomJS, possiamo effettivamente caricare qualsiasi URL e lavorare con la pagina da due punti di vista:
Iniziamo scegliendo di caricare una pagina. Crea un nuovo file di script e aggiungi il seguente codice:
var page = require ('pagina web'). create (); page.open ('http://net.tutsplus.com', funzione (s) console.log (s); phantom.exit (););
Iniziamo caricando PhantomJS ' pagina web
modulo e creazione di un oggetto pagina web. Quindi chiamiamo il Aperto
metodo, passandogli un URL e una funzione di callback; è all'interno di questa funzione di callback che possiamo interagire con la pagina attuale. Nell'esempio sopra, registriamo semplicemente lo stato della richiesta, fornito dal parametro della funzione di callback. Se si esegue questo script (con phantomjs script.js
), dovresti ottenere "successo" stampato nel terminale.
Ma rendiamo questo più interessante caricando una pagina e eseguendo alcuni JavaScript su di essa. Iniziamo con il codice sopra, ma a questo punto effettuiamo una chiamata page.evaluate
:
page.open ('http://net.tutsplus.com', function () var title = page.evaluate (function () var posts = document.getElementsByClassName ("post"); post [0]. stile. backgroundColor = "# 000000"; return document.title;); page.clipRect = top: 0, left: 0, width: 600, height: 700; page.render (title + ".png"); phantom .Uscita(); );
PhantomJS è un browser, ma un browser senza testa.
La funzione che passiamo a page.evaluate
viene eseguito come JavaScript nella pagina Web caricata. In questo caso, troviamo tutti gli elementi con il inviare
classe; quindi, impostiamo lo sfondo del primo post in nero. Alla fine, restituiamo il titolo del documento
. Questa è una bella funzionalità, che restituisce un valore dal nostro valutare
richiamata e assegnandola a una variabile (in questo caso, titolo
).
Quindi, impostiamo il clipRect
sulla pagina; queste sono le dimensioni per lo screenshot che prendiamo con rendere
metodo. Come puoi vedere, impostiamo il superiore
e sinistra
valori per impostare il punto di partenza e abbiamo anche impostato a larghezza
e altezza
. Infine, chiamiamo page.render
, passandogli un nome per il file (il titolo
variabile). Quindi, finiamo chiamando phantom.exit ()
.
Vai avanti ed esegui questo script, e dovresti avere un'immagine simile a questa:
Puoi vedere entrambi i lati della moneta PhantomJS qui: possiamo eseguire JavaScript dall'interno della pagina, e anche eseguire dall'esterno, sull'istanza stessa della pagina.
Questo è stato divertente, ma non incredibilmente utile. Concentriamoci sull'utilizzo di PhantomJS durante il test del nostro JavaScript relativo al DOM.
Yeoman usa PhantomJS nella sua procedura di test, ed è praticamente senza cuciture.
Per un sacco di codice JavaScript, puoi testare senza bisogno di un DOM, ma ci sono momenti in cui i tuoi test devono lavorare con elementi HTML. Se sei come me e preferisci eseguire test sulla riga di comando, è qui che entra in gioco PhantomJS.
Naturalmente, PhantomJS non è una libreria di test, ma molte delle altre librerie di test popolari possono essere eseguite su PhantomJS. Come puoi vedere dalla pagina wiki di PhantomJS sui test senza testa, i runner di test di PhantomJS sono disponibili per quasi tutte le librerie di test che potresti voler utilizzare. Diamo un'occhiata a come usare PhantomJS con Jasmine e Mocha.
In primo luogo, Jasmine e un disclaimer: non c'è un buon corridore di PhantomJS per Jasmine in questo momento. Se usi Windows e Visual Studio, dovresti controllare Chutzpah, e gli sviluppatori di Rails dovrebbero provare guard-jasmine. Ma a parte questo, il supporto di Jasmine + PhantomJS è scarso.
Per questo motivo, ti consiglio di usare Mocha per i test relativi al DOM.
PERÒ.
È possibile che tu abbia già un progetto utilizzando Jasmine e desideri utilizzarlo con PhantomJS. Un progetto, fantasma-gelsomino, richiede un po 'di lavoro da impostare, ma dovrebbe fare il trucco.
Iniziamo con una serie di test JasmineJS. Scarica il codice per questo tutorial (link in alto), e controlla il jasmine-starter
cartella. Vedrai che abbiamo un singolo tests.js
file che crea un elemento DOM, imposta alcune proprietà e lo aggiunge al corpo. Quindi, eseguiamo alcuni test Jasmine per garantire che il processo abbia funzionato correttamente. Ecco il contenuto di quel file:
descrivere ("DOM Tests", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Ciao!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" è nel DOM ", function () expect (myEl) .not.toBeNull ();); ("è un figlio del corpo", function () expect (myEl.parentElement) .toBe (document.body);); it ("ha il testo giusto", function () expect (myEl.innerHTML ) .toEqual ("Ciao!");); it ("ha lo sfondo giusto", function () expect (myEl.style.background) .toEqual ("rgb (204, 204, 204)"); ););
Il SpecRunner.html
il file è abbastanza disponibile; l'unica differenza è che ho spostato i tag dello script nel corpo per garantire che il DOM venga caricato completamente prima dell'esecuzione dei test. Puoi aprire il file in un browser e vedere che tutti i test passano bene.
Passiamo questo progetto a PhantomJS. In primo luogo, clonare il progetto fantasma-gelsomino:
git clone git: //github.com/jcarver989/phantom-jasmine.git
Questo progetto non è organizzato come potrebbe essere, ma ci sono due parti importanti che ti servono:
Entrambi questi file risiedono nel lib
cartella; copiarli in jasmine-starter / lib
. Ora dobbiamo aprire il nostro SpecRunner.html
file e regolare il elements. Here's what they should look like:
Si noti che abbiamo due reporter per i nostri test: un reporter HTML e un reporter della console. Questo significa SpecRunner.html
e i suoi test possono essere eseguiti sia nel browser che nella console. È utile. Sfortunatamente, dobbiamo averlo console_reporter
variabile perché è utilizzata all'interno del file CoffeeScript che stiamo per eseguire.
Quindi, come facciamo realmente a eseguire questi test sulla console? Supponendo che tu sia nel jasmine-starter
cartella sul terminale, ecco il comando:
phantomjs lib / run \ _jasmine \ _test.coffee ./SpecRunner.html
Stiamo eseguendo il eseguire \ _jasmine \ _test.coffee
script con PhantomJS e passando il nostro SpecRunner.html
file come parametro. Dovresti vedere qualcosa di simile a questo:
Naturalmente, se un test fallisce, vedrai qualcosa di simile al seguente:
Se pensi di usarlo spesso, potrebbe essere una buona idea spostarti eseguire \ _jasmine \ _test.coffee
in un'altra posizione (come ~ / Bin / run \ _jasmine \ _test.coffee
) e creare un alias terminale per l'intero comando. Ecco come lo faresti in una shell Bash:
alias phantom-jasmine = "phantomjs /path/to/run\_jasmine\_test.coffee"
Basta buttarlo nella tua .bashrc
o .bash_profile
file. Ora puoi solo eseguire:
fantasma-gelsomino SpecRunner.html
Ora i tuoi test Jasmine funzionano bene sul terminale tramite PhantomJS. Puoi vedere il codice finale nel gelsomino-totale
cartella nel download.
Per fortuna, è molto più facile integrare Mocha e PhantomJS con mocha-phantomjs. È semplicissimo da installare se hai installato NPM (che dovresti):
npm install -g mocha-phantomjs
Questo comando installa a moka phantomjs
binario che useremo per eseguire i nostri test.
In un precedente tutorial, ti ho mostrato come usare Mocha nel terminale, ma farai le cose in modo diverso quando lo utilizzerai per testare il codice DOM. Come con Jasmine, inizieremo con un reporter di test HTML che può essere eseguito nel browser. La bellezza di questo è che saremo in grado di eseguire lo stesso file sul terminale per i risultati dei test della console con PhantomJS; proprio come potremmo fare con Jasmine.
Quindi, costruiamo un progetto semplice. Crea una directory di progetto e spostati in essa. Inizieremo con a package.json
file:
"nome": "progetto", "versione": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"
Mocha è il framework di test e useremo Chai come libreria di asserzioni. Installiamo questi eseguendo NPM.
Chiameremo il nostro file di test test / tests.js
, e qui ci sono i suoi test:
descrivere ("DOM Tests", function () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Ciao!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); it (" è nel DOM ", function () expect (myEl) .to.not.equal (null); ); it ("è un figlio del corpo", function () expect (myEl.parentElement) .to.equal (document.body);); it ("ha il testo giusto", function () expect (myEl.innerHTML) .to.equal ("Ciao!");); it ("ha lo sfondo giusto", function () expect (myEl.style.background) .to.equal ("rgb ( 204, 204, 204) ");););
Sono molto simili ai test di Jasmine, ma la sintassi dell'asserzione di Chai è un po 'diversa (quindi non copiare i tuoi test di Jasmine).
L'ultimo pezzo del puzzle è il TestRunner.html
file:
test
Ci sono diversi fattori importanti qui. Innanzitutto, nota che questo è abbastanza completo da essere eseguito in un browser; abbiamo il CSS e JavaScript dai moduli del nodo che abbiamo installato. Quindi, nota il tag script inline. Determina se PhantomJS è caricato e, in tal caso, esegue la funzionalità PhantomJS. In caso contrario, si attacca con la funzionalità Mocha raw. Puoi provare questo nel browser e vederlo funzionare.
Per eseguirlo nella console, esegui semplicemente questo:
mocha-phantomjs TestRunner.html
Ecco! Ora i test vengono eseguiti nella console, ed è tutto grazie a PhantomJS.
Scommetto che non sapevi che il popolare Yeoman usa PhantomJS nella sua procedura di test, ed è sostanzialmente inesistente. Diamo un'occhiata ad un rapido esempio. Immagino che tu abbia Yeoman tutto pronto.
Crea una nuova directory di progetto, corri yeoman init
al suo interno e rispondi "No" a tutte le opzioni. Apri il test / index.html
file, e troverai un tag script vicino in fondo con un commento che ti dice di sostituirlo con le tue specifiche. Ignora completamente quel buon consiglio e mettilo dentro esso
bloccare:
var el = document.createElement ("div"); si aspettano (el.tagName) .to.equal ( "DIV");
Adesso corri test degli yeoman
, e vedrai che il test funziona bene. Ora aperto test / index.html
file nel browser. Funziona! Perfezionare!
Certo, c'è molto di più che puoi fare con Yeoman, quindi dai un'occhiata alla documentazione di più.
Usa le librerie che estendono PhantomJS per semplificare i tuoi test.
Se stai usando PhantomJS da solo, non c'è alcun motivo per conoscere PhantomJS stesso; puoi semplicemente sapere che esiste e utilizzare le librerie che estendono PhantomJS per semplificare i test.
Spero che questo tutorial ti abbia incoraggiato a esaminare PhantomJS. Consiglio di iniziare con i file di esempio e la documentazione offerta da PhantomJS; apriranno davvero gli occhi su ciò che puoi fare con PhantomJS - tutto dall'automazione delle pagine allo sniffing della rete.
Così, può pensi a un progetto che PhantomJS migliorerebbe? Ne sentiamo parlare nei commenti!