Jeg tror ikke jeg må overbevise deg om at det å teste JavaScript-koden din er en god ide. Men det kan noen ganger være kjedelig å teste JavaScript-kode som krever et DOM. Dette betyr at du må teste koden din i nettleseren og ikke kan bruke terminalen, ikke sant? Feil, faktisk: skriv inn PhantomJS.
Hva er PhantomJS? Vel, her er en blurb fra PhantomJS nettsiden:
PhantomJS er en headless WebKit med JavaScript API.
Som du vet, er Webkit den layoutmotor som Chrome, Safari og noen andre nisjebrowserer bruker. Så PhantomJS er en nettleser, men en headless nettleser. Dette betyr at de gjengitte nettsidene aldri blir vist. Dette kan høres rart ut mot deg; slik at du kan tenke på det som en programmerbar nettleser for terminalen. Vi ser på et enkelt eksempel om et minutt, men vi må først installere PhantomJS.
Installere PhantomJS er faktisk ganske enkelt: det er bare et enkelt binært som du laster ned og stikker i din terminale bane. På PhantomJS nedlastingssiden, velg operativsystemet og last ned den riktige pakken. Flytt deretter binærfilen fra den nedlastede pakken til en katalog i din terminalbane (jeg liker å sette inn denne typen ting ~ / Bin
).
Hvis du er på Mac OS X, er det en enklere måte å installere PhantomJS på (og dette er faktisk metoden jeg brukte). Bare bruk Homebrew, slik:
bryg oppdatering & & brygg installasjonsfantomier
Du bør nå ha PhantomJS installert. Du kan dobbeltsjekke installasjonen din ved å kjøre dette:
fantom - versjon
Jeg ser 1.7.0; du?
La oss starte med et lite eksempel.
console.log ("vi kan logge ting ut."); funksjon legg til (a, b) return a + b; conslole.log ("Vi kan også utføre vanlig JS:", legg til (1, 2)); phantom.exit ();
Gå videre og kjør denne koden ved å utstede følgende kommando:
phantomjs simple.js
Du bør se produksjonen fra de to console.log
linjer i terminalvinduet.
Sikker, dette er enkelt, men det gjør et godt poeng: PhantomJS kan utføre JavaScript akkurat som en nettleser. Dette eksemplet har imidlertid ingen PhantomJS-spesifikk kode ... vel, bortsett fra den siste linjen. Det er en viktig linje for hvert PhantomJS-skript fordi det går ut av skriptet. Dette kan ikke være fornuftig her, men husk at JavaScript ikke alltid utfører lineært. For eksempel kan det være lurt å sette exit()
ring inn en tilbakeringingsfunksjon.
La oss se på et mer komplekst eksempel.
Ved hjelp av PhantomJS API kan vi faktisk laste inn en hvilken som helst nettadresse og jobbe med siden fra to perspektiver:
La oss begynne med å velge å laste inn en side. Opprett en ny skriptfil og legg til følgende kode:
var side = krever ('webside'). opprett (); page.open ('http://net.tutsplus.com', funksjon (er) console.log (s); phantom.exit (););
Vi begynner med å laste PhantomJS ' nettside
modul og lage en nettsideobjekt. Vi kaller da åpen
metode, passerer den en URL og en tilbakeringingsfunksjon; Det er inne i denne tilbakeringingsfunksjonen som vi kan samhandle med den faktiske siden. I eksempelet ovenfor logger vi bare statusen til forespørselen, som tilbys av tilbakeringingsfunksjonens parameter. Hvis du kjører dette skriptet (med phantomjs script.js
), bør du få "suksess" trykt i terminalen.
Men la oss gjøre dette mer interessant ved å laste inn en side og utføre noen JavaScript på den. Vi starter med koden ovenfor, men vi ringer da til page.evaluate
:
side.open ('http://net.tutsplus.com', funksjon () var title = page.evaluate (funksjon () var innlegg = document.getElementsByClassName ("post"); innlegg [0] .style. backgroundColor = "# 000000"; return document.title;); page.clipRect = topp: 0, venstre: 0, bredde: 600, høyde: 700; side.render (tittel + ".png"); .exit(); );
PhantomJS er en nettleser, men en headless nettleser.
Funksjonen som vi sender til page.evaluate
kjøres som JavaScript på den lastede websiden. I dette tilfellet finner vi alle elementene med post
klasse; da satte vi bakgrunnen til det første innlegget til svart. Til slutt returnerer vi dokument tittel
. Dette er en fin funksjon, som returnerer en verdi fra vår evaluere
tilbakeringing og tilordne den til en variabel (i dette tilfellet, tittel
).
Så satte vi clipRect
på siden; Dette er dimensjonene for skjermbildet vi tar med gjengi
metode. Som du kan se, setter vi inn topp
og venstre
verdier for å angi startpunktet, og vi stiller også a bredde
og høyde
. Til slutt, vi ringer page.render
, sender det et navn til filen (den tittel
variabel). Så slutter vi ved å ringe phantom.exit ()
.
Gå videre og kjør dette skriptet, og du bør ha et bilde som ser noe ut som dette:
Du kan se begge sider av PhantomJS-mynten her: Vi kan utføre JavaScript fra innsiden av siden, og også utføre fra utsiden, på siden forekomsten selv.
Dette har vært morsomt, men ikke utrolig nyttig. La oss fokusere på å bruke PhantomJS når du tester vår DOM-relaterte JavaScript.
Yeoman bruker PhantomJS i testprosedyren, og det er nesten sømløst.
For mye JavaScript-kode kan du teste uten å ha behov for et DOM, men det er tider når testene dine må fungere med HTML-elementer. Hvis du er som meg og foretrekker å kjøre tester på kommandolinjen, er dette PhantomJS som kommer inn i spill.
Selvfølgelig er PhantomJS ikke et testbibliotek, men mange av de andre populære testbiblioteker kan kjøre på toppen av PhantomJS. Som du kan se fra PhantomJS wiki-siden på headless testing, er PhantomJS testløpere tilgjengelig for stort sett hvert testbibliotek du kanskje vil bruke. La oss se på hvordan du bruker PhantomJS med jasmin og mokka.
Først, Jasmine og en ansvarsfraskrivelse: det er ikke en god PhantomJS løper for Jasmine på dette tidspunktet. Hvis du bruker Windows og Visual Studio, bør du sjekke ut Chutzpah, og Rails-utviklere bør prøve vakt-jasmin. Men bortsett fra det, er Jasmine + PhantomJS-støtten sparsom.
Av denne grunn anbefaler jeg at du bruker Mokka til DOM-relaterte tester.
DERIMOT.
Det er mulig at du allerede har et prosjekt ved hjelp av Jasmine og vil bruke det med PhantomJS. Ett prosjekt, fantom-jasmin, tar litt arbeid å sette opp, men det bør gjøre kunsten.
La oss begynne med et sett med JasmineJS-tester. Last ned koden for denne opplæringen (link øverst), og sjekk ut jasmin-starter
mappe. Du ser at vi har en singel tests.js
fil som lager et DOM-element, setter noen egenskaper, og legger det til kroppen. Deretter løper vi noen jasmintester for å sikre at prosessen fungerte riktig. Her er innholdet i den filen:
Beskriv ("DOM-test", funksjon () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hei!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); det (" er i DOM ", funksjon () forvente (myEl) .not.toBeNull ();); det ("er et barn av kroppen", funksjon () (forvent (myEl.parentElement) .toBe (document.body);); den ("har den riktige teksten", funksjonen () forventer (myEl.innerHTML ) .tilEkvivalent ("Hei!");); det ("har den riktige bakgrunnen", funksjonen () (forvent (myEl.style.background) .tilEqual ("rgb (204, 204, 204)"); );;
De SpecRunner.html
filen er ganske lager; Den eneste forskjellen er at jeg flyttet skriptetikettene inn i kroppen for å sikre at DOM er fullstendig lastet før testene våre går. Du kan åpne filen i en nettleser og se at alle tester passerer bra.
La oss overgå dette prosjektet til PhantomJS. Først klon fantom-jasminprosjektet:
git klon git: //github.com/jcarver989/phantom-jasmine.git
Dette prosjektet er ikke så organisert som det kunne være, men det er to viktige deler du trenger fra det:
Begge disse filene ligger i lib
mappe; kopier dem til jasmin-starter / lib
. Vi må nå åpne vår SpecRunner.html
fil og juster elements. Here's what they should look like:
Legg merke til at vi har to reportere for våre tester: en HTML-reporter og en konsoll reporter. Dette betyr SpecRunner.html
og dens tester kan kjøre i både nettleseren og konsollen. Det er praktisk. Dessverre må vi ha det console_reporter
variabel fordi den brukes i CoffeeScript-filen vi skal kjøre.
Så, hvordan går det om å faktisk kjøre disse testene på konsollen? Forutsatt at du er i jasmin-starter
mappe på terminalen, her er kommandoen:
phantomjs lib / run \ _jasmine \ _test.coffee ./SpecRunner.html
Vi kjører kjøre \ _jasmine \ _test.coffee
skript med PhantomJS og passerer vår SpecRunner.html
filen som en parameter. Du bør se noe slikt:
Selvfølgelig, hvis en test mislykkes, ser du noe som følger:
Hvis du planlegger å bruke dette ofte, kan det være lurt å flytte kjøre \ _jasmine \ _test.coffee
til et annet sted (som ~ / Bin / løpe \ _jasmine \ _test.coffee
) og opprett et terminalalias for hele kommandoen. Slik gjør du det i et Bash-skall:
alias phantom-jasmine = "phantomjs /path/to/run\_jasmine\_test.coffee"
Bare kast det i din .bashrc
eller .bash_profile
fil. Nå kan du bare kjøre:
phantom-jasmin SpecRunner.html
Nå jobber jasminestesterene fint på terminalen via PhantomJS. Du kan se den endelige koden i jasmin-total
mappe i nedlastingen.
Heldigvis er det mye lettere å integrere Mokka og PhantomJS med mokka-fantomier. Det er veldig enkelt å installere hvis du har installert NPM (som du burde):
npm installere -g mocha-phantomjs
Denne kommandoen installerer a mocha-phantomjs
binær som vi vil bruke til å kjøre testene våre.
I en tidligere opplæring viste jeg deg hvordan du bruker Mokka i terminalen, men du vil gjøre ting annerledes når du bruker den til å teste DOM-koden. Som med Jasmine begynner vi med en HTML-testreporter som kan kjøre i nettleseren. Skjønnheten i dette er at vi vil kunne kjøre den samme filen på terminalen for konsolltestresultater med PhantomJS; akkurat som vi kunne med Jasmine.
Så la oss bygge et enkelt prosjekt. Lag en prosjektkatalog og flytt inn i den. Vi starter med en package.json
fil:
"navn": "prosjekt", "versjon": "0.0.1", "devDependencies": "mocha": "*", "chai": "*"
Mokka er testrammen, og vi bruker Chai som vårt påstandsbibliotek. Vi installerer disse ved å kjøre NPM.
Vi ringer vår testfil test / tests.js
, og her er tester:
Beskriv ("DOM-test", funksjon () var el = document.createElement ("div"); el.id = "myDiv"; el.innerHTML = "Hei!"; el.style.background = "#ccc "; document.body.appendChild (el); var myEl = document.getElementById ('myDiv'); det (" er i DOM ", funksjon () forvente (myEl) .to.not.equal (null); ), det ("er et barn av kroppen", funksjonen () (forvent (myEl.parentElement) .to.equal (document.body);); den ("har den rette teksten" Forvent (myEl.innerHTML) .to.equal ("Hei!");); den ("har den riktige bakgrunnen", funksjonen () forventer (myEl.style.background) .to.equal ("rgb 204, 204, 204) ");););
De er veldig lik Jasmine-tester, men Chai-påstandssyntaxen er litt annerledes (så ikke bare kopier Jasmine-testene).
Det siste stykket av puslespillet er TestRunner.html
fil:
tester
Det er flere viktige faktorer her. Først legg merke til at dette er komplett nok til å kjøre i en nettleser; Vi har CSS og JavaScript fra nodemodulene som vi installerte. Legg merke til inline script-merket. Dette bestemmer om PhantomJS er lastet, og i så fall kjører PhantomJS-funksjonaliteten. Ellers stikker den med rå Mocha-funksjonalitet. Du kan prøve dette ut i nettleseren og se det fungere.
For å kjøre det i konsollen, bare kjør dette:
mocha-phantomjs TestRunner.html
Voila! Nå er du tester i konsollen, og det er alt takket være PhantomJS.
Jeg vil satse på at du ikke visste at den populære Yeoman bruker PhantomJS i sin testprosedyre, og det er vritt ubøyelig. La oss se på et raskt eksempel. Jeg antar at du har Yeoman alle satt opp.
Opprett et nytt prosjektkatalog, kjør yeoman init
inne i det, og svar "Nei" til alle alternativene. Åpne test / indeks.html
fil, og du finner et skript-tag nær bunnen med en kommentar som forteller deg å erstatte den med dine egne spesifikasjoner. Helt ignorere det gode råd og legg dette inn i den
blokkere:
var el = document.createElement ("div"); forvente (el.tagName) .to.equal ( "DIV");
Kjør nå yeoman test
, og du vil se at testen går bra. Nå åpen test / indeks.html
fil i nettleseren. Det fungerer! Perfekt!
Selvfølgelig er det mye mer du kan gjøre med Yeoman, så sjekk ut dokumentasjonen for mer.
Bruk biblioteker som utvider PhantomJS for å gjøre testingen enklere.
Hvis du bruker PhantomJS alene, er det ikke noen grunn til å lære om PhantomJS selv; du kan bare vite at det eksisterer og bruke bibliotekene som utvider PhantomJS for å gjøre testingen enklere.
Jeg håper denne opplæringen har oppfordret deg til å se på PhantomJS. Jeg anbefaler å starte med eksempelfiler og dokumentasjon som PhantomJS tilbyr; de vil virkelig åpne øynene dine for hva du kan gjøre med PhantomJS - alt fra sideautomatisering til nettverkssnusing.
Så, kan tenker du på et prosjekt som PhantomJS ville forbedre? La oss høre om det i kommentarene!