Testarea JavaScript cu PhantomJS

Nu cred că trebuie să vă conving că testarea codului dvs. JavaScript este o idee bună. Dar, uneori, se poate dovedi dificil să testați codul JavaScript care necesită un DOM. Aceasta înseamnă că trebuie să testați codul în browser și nu puteți folosi terminalul, nu? În mod greșit, de fapt: introduceți PhantomJS.


Ce anume este PhantomJS? Ei bine, iată un blurb de pe site-ul PhantomJS:

PhantomJS este un WebKit fără cap și JavaScript API.

După cum știți, Webkit este motorul de layout pe care îl folosesc Chrome, Safari și alte browsere de nișă. Deci PhantomJS este un browser, dar un browser fără cap. Aceasta înseamnă că paginile Web redate nu sunt niciodată afișate. Acest lucru poate părea ciudat pentru dvs.; astfel încât să vă puteți gândi la acesta ca la un browser programabil pentru terminal. Ne vom uita la un exemplu simplu într-un minut, dar mai întâi trebuie să instalăm PhantomJS.


Instalarea PhantomJS

Instalarea lui PhantomJS este de fapt destul de simplă: este doar un singur binar pe care îl descărcați și îl țineți în calea terminalului. Pe pagina de descărcare PhantomJS, alegeți sistemul de operare și descărcați pachetul corect. Apoi, mutați fișierul binar din pachetul descărcat într-un director din calea terminalului dvs. (îmi place să pun acest gen de lucruri înăuntru ~ / Bin).

Dacă sunteți pe Mac OS X, există o modalitate mai simplă de a instala PhantomJS (și aceasta este de fapt metoda pe care am folosit-o). Utilizați doar Homebrew, astfel:

pregătiți actualizarea && brew install phantomjs

Acum ar trebui să aveți instalat PhantomJS. Puteți să vă verificați din nou instalarea prin executarea acesteia:

phantomjs --versiune

Văd 1.7.0; tu?


Un exemplu mic

Să începem cu un mic exemplu.

simple.js
console.log ("ne putem loga lucrurile afară"); adăugați funcția (a, b) return a + b;  conslole.log ("Putem executa și JS regulat:", adăugați (1, 2)); phantom.exit ();

Mergeți mai departe și executați acest cod prin emiterea următoarei comenzi:

phantomjs simple.js

Ar trebui să vedeți ieșirea din cele două console.log linii în fereastra terminalului.

Sigur, acest lucru este simplu, dar face un punct bun: PhantomJS poate executa JavaScript exact ca un browser. Cu toate acestea, acest exemplu nu are nici un cod specific PhantomJS ... bine, în afară de ultima linie. Aceasta este o linie importantă pentru fiecare script PhantomJS deoarece iese din scenariu. Acest lucru nu are sens aici, dar amintiți-vă că JavaScript nu execută întotdeauna liniar. De exemplu, ați putea dori să puneți Ieșire() apel într-o funcție de apel invers.

Să examinăm un exemplu mai complex.


Încărcarea paginilor

Folosind API-ul PhantomJS, putem să încărcăm orice URL și să lucrăm cu pagina din două perspective:

  • ca JavaScript pe pagină.
  • ca utilizator în căutarea paginii.

Să începem prin alegerea de a încărca o pagină. Creați un fișier script nou și adăugați următorul cod:

script.js
var pagina = necesită ("pagina web"). create (); page.open ('http://net.tutsplus.com', funcții console.log (s); phantom.exit (););

Începem prin încărcarea lui PhantomJS " pagină web modul și crearea unui obiect de pagină web. Apoi chemăm deschis metodă, oferindu-i o adresă URL și o funcție de apel invers; este în interiorul acestei funcții de apel invers că putem interacționa cu pagina actuală. În exemplul de mai sus, doar logăm starea solicitării, furnizată de parametrul funcției de apel invers. Dacă executați acest script (cu phantomjs script.js), ar trebui să obțineți "succesul" tipărit în terminal.

Dar hai să facem acest lucru mai interesant prin încărcarea unei pagini și executarea unor JavaScript pe ea. Începem cu codul de mai sus, dar suntem la telefon page.evaluate:

pagina.open ('http://net.tutsplus.com', functie () var title = page.evaluate (function () var post = document.getElementsByClassName ("post"); background.clipRect = top: 0, left: 0, width: 600, height: 700; page.render (title + ".png"); phantom .Ieșire(); );

PhantomJS este un browser, dar un browser fără cap.

Funcția la care trecem page.evaluate execută ca JavaScript pe pagina web încărcată. În acest caz, găsim toate elementele cu post clasă; apoi, am setat fundalul primului post pe negru. În cele din urmă, returnează titlul documentului. Aceasta este o caracteristică plăcută, întorcând o valoare din partea noastră a evalua apel invers și alocarea acesteia unei variabile (în acest caz, titlu).

Apoi, am setat clipRect pe pagină; acestea sunt dimensiunile pentru captura de ecran pe care le facem cu face metodă. După cum puteți vedea, am setat top și stânga valorile pentru a seta punctul de pornire și setăm și a lăţime și înălţime. În cele din urmă, sunăm page.render, trecându-i un nume pentru fișier ( titlu variabil). Apoi, terminăm prin apelarea phantom.exit ().

Continuați și rulați acest script și ar trebui să aveți o imagine care arată astfel:

Puteți vedea ambele fețe ale monedei PhantomJS aici: putem executa JavaScript din interiorul paginii și execută și din exterior, în instanța de pagină în sine.

Acest lucru a fost distractiv, dar nu foarte utile. Să ne concentrăm pe utilizarea PhantomJS atunci când testează JavaScript-ul nostru legat de DOM.


Testarea cu PhantomJS

Yeoman folosește PhantomJS în procedura de testare și este practic fără probleme.

Pentru o mulțime de cod JavaScript, puteți testa fără a avea nevoie de un DOM, dar sunt momente în care testele dvs. trebuie să funcționeze cu elemente HTML. Dacă sunteți ca mine și preferați să executați teste pe linia de comandă, acesta este locul unde PhantomJS intră în joc.

Desigur, PhantomJS nu este o bibliotecă de testare, dar multe dintre celelalte biblioteci populare de testare pot rula pe partea de sus a PhantomJS. După cum puteți vedea din pagina wiki PhantomJS privind testarea fără cap, alergătorii de testare PhantomJS sunt disponibili pentru aproape orice bibliotecă de testare pe care ați putea dori să o utilizați. Să ne uităm cum să folosim PhantomJS cu Jasmine și Mocha.

În primul rând, Jasmine și o declarație de respingere: nu există un bun alergător PhantomJS pentru Jasmine în acest moment. Dacă utilizați Windows și Visual Studio, ar trebui să verificați Chutzpah, iar dezvoltatorii Rails ar trebui să încerce să păstreze-iasomia. Dar altceva decât acela, sprijinul Jasmine + PhantomJS este rar.

Din acest motiv, vă recomandăm să utilizați Mocha pentru teste legate de DOM.

IN ORICE CAZ.

Este posibil să aveți deja un proiect folosind Jasmine și doriți să îl utilizați cu PhantomJS. Un proiect, fantomă-iasomie, are nevoie de puțină muncă pentru a se înființa, dar ar trebui să facă truc.

Să începem cu un set de teste JasmineJS. Descărcați codul pentru acest tutorial (link-ul din partea de sus) și verificați iasomie-starter pliant. Veți vedea că avem un singur tests.js fișierul care creează un element DOM, stabilește câteva proprietăți și îl adaugă corpului. Apoi, rulați câteva teste de iasomie pentru a vă asigura că procesul a funcționat corect. Iată conținutul acelui fișier:

tests.js
descrie ("Teste DOM", funcția () var el = document.createElement ("div"); el.id = "myDiv"; "document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); aceasta (" este în DOM ", funcția () expect (myEl) .not.toBeNull ();); ("este un copil al corpului", funcția () aștepta (myEl.parentElement) .toBe (document.body);) ("are textul potrivit", funcția () așteptați (myEl.innerHTML ) .toEqual ("Bună!");); ("are fundalul potrivit", funcția () așteptați (myEl.style.background) .toEqual ("rgb (204, 204, 204)"); ););

SpecRunner.html fișierul este destul de stoc; singura diferență este că am mutat etichetele de scripturi în corp pentru a vă asigura că DOM-ul se încarcă complet înainte de a începe testele. Puteți deschide fișierul într-un browser și puteți vedea că toate testele au trecut bine.

Să trecem acest proiect la PhantomJS. Mai întâi, clonați proiectul fantomă-iasomie:

git clona git: //github.com/jcarver989/phantom-jasmine.git

Acest proiect nu este la fel de organizat cum ar putea fi, dar există două părți importante de care aveți nevoie:

  • alergătorul PhantomJS (care face ca Jasmine să utilizeze un DOM PhantomJS).
  • reporterul de consolă Jasmine (care oferă ieșirea consolei).

Ambele fișiere se află în lib pliant; copiați-le în iasomie-starter / lib. Acum trebuie să ne deschidem SpecRunner.html fișier și ajustați

Observați că avem doi reporteri pentru testele noastre: un reporter HTML și un reporter în consola. Asta înseamnă SpecRunner.html iar testele sale pot rula atât în ​​browser, cât și în consola. Asta e la îndemână. Din nefericire, trebuie să avem asta console_reporter deoarece este folosit în interiorul fișierului CoffeeScript pe care urmează să-l executăm.

Deci, cum să procedăm cu aceste teste la consola? Presupunând că ești în iasomie-starter folder pe terminal, iată comanda:

phantomjs lib / run \ _jasmine \ _test.coffee./SpecRunner.html

Descurcăm rula \ _jasmine \ _test.coffee scenariu cu PhantomJS și trecerea noastră SpecRunner.html fișier ca parametru. Ar trebui să vedeți ceva de genul:

Desigur, dacă un test nu reușește, veți vedea ceva de genul:

Dacă intenționați să folosiți acest lucru frecvent, ar fi o idee bună să vă mișcați rula \ _jasmine \ _test.coffee la o altă locație (cum ar fi ~ / Bin / rula \ _jasmine \ _test.coffee) și să creați un alias terminal pentru întreaga comandă. Iată cum ați face acest lucru într-un shell Bash:

alias phantom-jasmine = "phantomjs /path/to/run\_jasmine\_test.coffee"

Doar arunca asta în tine .bashrc sau .bash_profile fişier. Acum, puteți rula:

Phantom-Jasmine SpecRunner.html

Acum, testele dvs. de Jasmine funcționează foarte bine pe terminal prin PhantomJS. Puteți vedea codul final în iasomie-totală folder în descărcare.


PhantomJS și Mocha

Din fericire, este mult mai ușor să integrezi Mocha și PhantomJS cu mocha-phantomjs. Este foarte ușor de instalat dacă aveți NPM instalat (pe care ar trebui să-l aveți):

npm instalează-g mocha-phantomjs

Această comandă instalează a mocha-phantomjs binar pe care îl vom folosi pentru a rula testele noastre.

Într-un tutorial anterior, v-am arătat cum să utilizați Mocha în terminal, dar veți face lucrurile în mod diferit atunci când îl folosiți pentru a testa codul DOM. La fel ca la Jasmine, vom începe cu un reporter de testare HTML care poate rula în browser. Frumusețea acestui lucru este că vom putea rula același fișier pe terminal pentru rezultatele testelor cu consola cu PhantomJS; la fel cum am putut cu Jasmine.

Deci, să construim un proiect simplu. Creați un director de proiect și mutați-l în el. Vom începe cu a package.json fişier:

"nume": "proiect", "versiune": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"

Mocha este cadrul de testare și vom folosi Chai ca bibliotecă de afirmare. Noi le instalăm prin rularea NPM.

Ne vom suna fișierul de test testare / tests.js, și aici sunt testele sale:

descrie ("Teste DOM", funcția () var el = document.createElement ("div"); el.id = "myDiv"; "document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); aceasta (" este în DOM ", funcția () așteptați (myEl) .to.not.equal (null); ); ea ("este un copil al corpului", functie () expect (myEl.parentElement) .to.equal (document.body); așteptați (myEl.innerHTML) .to.equal ("Hi there!");)); ea ("are fundalul potrivit", funcția () expect (myEl.style.background) .to.equal 204, 204, 204));););

Sunt foarte asemănătoare cu testele Jasmine, dar sintaxa de afirmație Chai este puțin diferită (deci nu copiați doar testele de Jasmine).

Ultima piesă a puzzle-ului este TestRunner.html fişier:

   teste     

Există aici câțiva factori importanți. Mai întâi, observați că aceasta este suficient de completă pentru a rula într-un browser; avem CSS și JavaScript din modulele de nod pe care le-am instalat. Apoi, observați eticheta de script inline. Aceasta determină dacă PhantomJS este încărcat și, dacă da, rulează funcționalitatea PhantomJS. În caz contrar, se lipsește de funcționalitatea primă Mocha. Puteți încerca acest lucru în browser și văd că funcționează.

Pentru ao rula în consola, pur și simplu rulați acest lucru:

mocha-phantomjs TestRunner.html

Voila! Acum ești testat în consola și totul este datorat PhantomJS.


PhantomJS și Yeoman

Pun pariu că nu știai că popularul Yeoman folosește PhantomJS în procedurile de testare și este în mod vădit nevăzut. Să examinăm un exemplu rapid. Presupun că ai făcut-o pe Yeoman.

Creați un nou director de proiect, rulați yeoman init înăuntru și răspundeți "Nu" la toate opțiunile. Deschide testare / index.html fișier și veți găsi o etichetă de script aproape de partea de jos cu un comentariu care vă spune să îl înlocuiți cu propriile specificații. Ignorați cu desăvârșire acest sfat bun și puneți-i înăuntru aceasta bloc:

var el = document.createElement ("div"); se așteaptă (el.tagName) .to.equal ( "DIV");

Acum fugi testul testului, și veți vedea că testul funcționează bine. Acum deschis testare / index.html fișier în browser. Functioneaza! Perfect!

Desigur, aveți multe de făcut cu Yeoman, deci verificați documentația pentru mai multe.


Concluzie

Utilizați bibliotecile care extind PhantomJS pentru a face testarea dvs. mai simplă.

Dacă utilizați PhantomJS pe cont propriu, nu există niciun motiv pentru a afla despre PhantomJS în sine; puteți ști că există și utilizați bibliotecile care extind PhantomJS pentru a face testul dvs. mai simplu.

Sper că acest tutorial te-a încurajat să te uiți în PhantomJS. Vă recomandăm să începeți cu exemplele de fișiere și documentația pe care PhantomJS le oferă; ei vor deschide cu adevărat ochii la ceea ce puteți face cu PhantomJS - totul de la automatizarea paginilor până la rețea.

Asa de, poate sa te gândești la un proiect pe care PhantomJS l-ar îmbunătăți? Să auzim despre asta în comentariile!

Cod