Headless funcțional de testare cu seleniu și PhantomJS

Să construim un sistem pentru efectuarea testelor funcționale asupra aplicațiilor web, utilizând Selenium și PhantomJS. Sistemul rezultat ne va permite să scriem scenarii de testare ușoare în JavaScript și să testăm acele scenarii atât în ​​browsere reale, cât și în simulatorul fără cap.


Alegerea componentelor

Dezavantajul evident al Selenium este că necesită un desktop grafic complet pentru toate testele.

Pentru a începe, trebuie să alegeți un control de browser sau un motor de emulare pentru a simula un utilizator final. Pentru mult timp, jucătorul principal în acest domeniu a fost Selenium, și încă mai este. Seleniul permite controlul automat al browserelor reale pe sisteme de operare reale, care este principalul avantaj: puteți fi absolut sigur că testele reprezintă realitatea cât mai aproape posibil.

Dezavantajul evident al Selenium este că necesită un desktop grafic complet pentru toate testele. Ca urmare, testele pot deveni lente. Cu toate acestea, Selenium poate fi fantastic, dacă aveți resursele necesare pentru a configura mașinile virtuale pentru diferite sisteme de operare și pentru a conecta toate împreună.

Pe partea opusă a spectrului este PhantomJS: Un proiect mic, dar excelent, care rulează un motor WebKit cu acces complet la JavaScript, dar fără porțiunea grafică. PhantomJS este un cinch pentru a configura, ruleaza pe orice masina, si este semnificativ mai rapid.

Selenium poate controla acum PhantomJS în același mod ca orice alt browser.

PhantomJS, fiind un WebKit complet, acoperă 90% din necesitățile dvs. de testare funcționale. La urma urmei, dacă aplicația dvs. rulează corect în WebKit, este probabil că va funcționa corect în alte browsere. Evident, acest lucru exclude Internet Explorer 6-8.

Cu toate acestea, pe măsură ce proiectul dvs. devine din ce în ce mai popular, restul de 10% devine o problemă semnificativă. Dacă suita dvs. de testare funcțională este instalată direct pe PhantomJS, ar fi o durere de rescriere a testelor pentru Selenium.

Din fericire, recent, aproape de sfarsitul anului 2012, am primit un cadou sub forma de legaturi PhantomJS catre Selenium. Cu alte cuvinte, Selenium poate controla acum PhantomJS în același mod ca orice alt browser.

Având în vedere că Selenium, în sine, nu are nevoie de o configurație complicată și poate rula oriunde, putem folosi legarea Selenium pentru a controla PhantomJS și pentru a acoperi 90% din nevoile noastre de testare. Dacă mai târziu aveți nevoie de teste mai puternice, puteți configura conexiuni extra de browser pentru Selenium fără a schimba o singură linie în codul dvs..

Astfel, alegerea noastră pentru motorul de navigare este Selenium cu PhantomJS.

Descrierea testelor

Selenium oferă legături în cele mai populare limbi de programare, astfel încât să putem alege o limbă în funcție de nevoile noastre. Aceasta este probabil cea mai controversată parte a acestui articol: consider că JavaScript este cea mai bună alegere pentru descrierea testelor funcționale pentru site-uri web și aplicații web.

  • Indiferent de tehnologia de back-end pe care o utilizați, partea front-end va folosi întotdeauna JavaScript (Acest lucru este valabil chiar dacă utilizați o limbă care compilează în jos la JavaScript de la vanilla, cum ar fi CoffeeScript sau TypeScript.). Ca atare, JavaScript va fi întotdeauna o limbă înțeleasă de cel puțin o persoană din echipa dvs..
  • Apoi, ia în considerare posibilitatea ca testele dvs. funcționale să fie scrise de către non-programatori. Popularitatea JavaScript-ului pe front-end, combinată cu expresivitatea în capacitatea de a crea limbi clare specifice domeniului, permite în mod clar mai multor persoane să scrie teste funcționale.
  • În cele din urmă, este normal să controlați un browser de testare cu JavaScript, având în vedere că este foarte asincron și este ceea ce controlam browserul zilnic.

Legarea seleniului pentru JavaScript este numită, webdriverjs. Deși proiectul este mai puțin matur decât driverele oficiale pentru Java, C #, Ruby și Python, acesta conține deja cea mai mare parte a funcționalității pe care o cerem.

Începeți testul

În scopul acestui articol, au fost selectate Mocha cu Chai.

În cele din urmă, avem nevoie de un alergator de testare sau de o aplicație pentru a rula testele după nume și de a tipări destul de bine rezultatul, observând însă câte încercări au reușit sau au eșuat. Acest testator ar trebui să ofere, de asemenea, o bibliotecă de afirmații, care permite coderului să exprime dacă un test reușește sau nu reușește.

Alegerea este absolut gratuită aici. Există o mulțime de alergători de testare JavaScript, dar în scopul acestui articol, Mocha cu Chai au fost selectați. Mocha oferă o cantitate considerabilă de flexibilitate, o mare varietate de formate de ieșire și sintaxa populară Jasmine. Chai vă permite să scrieți afirmații descriptive BDD.


Înființat

Iată stiva finală pe care o vom folosi:

  1. Mocha - alergător de test
  2. Chai - bibliotecă de afirmare
  3. webdriverjs - legături de control ale browserului
  4. Selenium - browser de abstractizare și fabrica de funcționare
  5. PhantomJS - browser rapid fără cap

Node.js și npm

Deoarece majoritatea stack-ului nostru se bazează pe JavaScript, avem nevoie de node.js și npm. Ambele sunt instrumente comune în comunitate și voi presupune că deja le-ați înființat. Dacă nu, utilizați programul de instalare pe site-ul web node.js. Nu-ți face griji; dacă se întâmplă ceva, există o mulțime de ghidaje de instalare a nodurilor disponibile pe web.

Mocha, Chai și webdriverjs

Toate cele trei pot fi instalate folosind NPM:

sudo npm instalare -g mocha chai webdriverjs

Alternativ, le puteți instala local în directorul în care se află testele dvs.:

npm instalați mocha chai webdriverjs

Seleniu

Descărcați serverul Selenium. Este distribuit ca un singur borcan fișier, pe care îl purtați simplu:

java -jar seleniu-server-standalone-2.28.0.jar

De îndată ce executați această comandă, aceasta pornește un server la care se va conecta ulterior codul dvs. de testare. Rețineți că va trebui să rulați Selenium Server de fiecare dată când executați testele.

PhantomJS

Versiunea rapidă

Utilizare NPM pentru a instala PhantomJS la nivel global:

sudo npm instalează -g phantomjs

Alte optiuni

Avem nevoie de o versiune nouă de PhantomJS - cel puțin 1.8. Aceasta înseamnă că pachetele furnizate de managerul de pachete (apt-get, MacPorts, ...) va fi, cel mai probabil, depășită.

Puteți instala utilizând npm fără o instalare globală sau folosind alte metode manual. În acest caz, totuși, va trebui să-i spuneți Selenium unde ați plasat PhantomJS de fiecare dată când executați Selenium:

PATH = "/ cale / spre / node_modules / phantomjs / bin: $ PATH" java -jar seleniu-server-standalone-2.28.0.jar

Combinând totul

Acum că avem toate piesele, trebuie să punem totul împreună.

Rețineți: înainte de a efectua orice teste, trebuie să rulați Selenium Server:

java -jar seleniu-server-standalone-2.28.0.jar

Seleniul va conduce PhantomJS intern; nu trebuie să vă faceți griji despre asta.

Acum, trebuie să ne conectăm la Selenium din JavaScript. Iată un fragment de probă, care va iniția o conexiune la Selenium și va avea un obiect gata pentru a controla instanța noastră de Selenium:

// Utilizați webdriverjs pentru a crea un Selenium Client var client = necesită ('webdriverjs'). Remote (desiredCapabilities: // Puteți alege alte browsere // http://code.google.com/p/selenium/wiki/ Browser-ul doritCapacități: "phantomjs", // webdriverjs are o mulțime de ieșiri, care este, în general, inutil. Totuși, dacă ceva nu merge bine, eliminați acest lucru pentru a vedea mai multe detalii logLevel: 'silent'); client.init ();

Acum, putem descrie testele noastre și le putem folosi client pentru a controla browserul. O referință completă pentru API-ul webdriverjs este disponibilă în documentație, dar aici este un exemplu scurt:

client.url ('http://example.com/') client.getTitle (funcția (titlu) console.log ('Titlul este', titlu);); client.setValue ('# field', 'value'); client.submitForm (); client.end ();

Să folosim sintaxa Mocha și Chai pentru a descrie un test; vom testa câteva proprietăți ale example.com pagină web:

descrie ('Test example.com', functie () inainte (functie (done) client.init () .url ('http://example.com' , funcția () it ('ar trebui să vadă titlul corect', funcția (făcut) client.getTitle (funcția (title) expect (title) .to.have.string; ;); acesta ("ar trebui să vadă corpul", funcția (done) client.getText ('p', function (p) expect (title) .to.have.string .));));)); după (funcția (done) client.end (); done ();););

S-ar putea să doriți să împărțiți unul client inițializare pe mai multe fișiere de testare. Creați un modul Nod mic pentru a-l inițializa și importa în fiecare fișier de testare:

client.js:

exports.client = cere ('webdriverjs'). remote (// Settings;

test.js:

var client = solicita ('./ client') client; var așteptați = solicitați ("chai") așteptați; // Efectuați teste

Alergare

Mocha suite de testare sunt executate cu cafea binar. Dacă ați urmat acest ghid și ați instalat local Mocha, atunci ar trebui să descrieți calea completă la binar: node_modules / Mocha / bin / Mocha.

Implicit, Mocha tratează orice test care durează mai mult de două secunde ca fiind eșuat. Dat fiind faptul că de fapt inițializăm un browser web și facem o solicitare HTTP, trebuie să mărim acest timp de expirare la 5 sau 10 secunde:

node_modules / mocha / bin / mocha test.js-t 10000

Dacă totul a mers conform planului, ar trebui să vedeți ieșirea astfel:

 . ✔ 1 test complet

Următorii pași

Odată ce ați obținut rezultatele testelor funcționale dorite, vă recomandăm să vă îmbunătățiți în continuare configurația.

Două direcții evidente sunt integrarea continuă și distribuirea testării seleniului.

Integrare continuă

Obiectivul dvs. ar trebui să fie acela de a minimiza timpul petrecut în timpul testelor.

S-ar putea să doriți să utilizați un server complet integrat de integrare continuă, care va executa testele ori de câte ori este nevoie automat și vă va informa dacă ceva nu merge bine.

În lumea open source, rolul unui astfel de server este acoperit de Jenkins CI: un serviciu convenabil, puternic și ușor de instalat, care va executa testele ori de câte ori este necesar, le va executa în orice configurație pe care o furnizați și, eventual, mai multe sarcini legate de construcție, cum ar fi implementarea codului dvs. pe servere la distanță.

Alternativ, dacă vă simțiți aventuros, puteți experimenta un nou proiect, numit GitLab CI, care oferă mai puține caracteristici, dar arată mai bine și este integrat cu GitLab, o clonă GitLab găzduită de sine.

În orice caz, obiectivul dvs. ar trebui să fie acela de a minimiza timpul petrecut în timpul testelor. În schimb, testele ar trebui executate automat și ar trebui doar să vă informeze dacă ceva nu merge bine.

Grila de seleniu

Seleniul are o serie de limitări de implementare. De exemplu, nu puteți rula mai mult de câteva browsere pe aceeași mașină pentru a fi testată cu Selenium.

În plus, veți observa că, odată ce ați efectuat mai multe teste, executarea tuturor acestora poate deveni un proces îndelungat. Deși integrarea continuă diminuează parțial această problemă, este posibil să doriți în continuare să efectuați câteva teste în paralel pe diferite mașini.

În cele din urmă, veți observa în curând că doriți să testați diferite browsere pe diferite sisteme de operare. Și, în timp ce codul dvs. de testare poate, teoretic, să vorbească cu diferite servere de Selenium, odată ce creșteți puțin, această configurare are nevoie de centralizare.

Seleniul Grid setup încearcă să ofere exact acest lucru. În loc să aveți un server de control al seleniului o grămadă de browsere pe o mașină, aveți un server Selenium, care controlează multiple noduri de seleniu, fiecare care controlează doar câteva browsere într-un singur sistem de operare.


Concluzie

Stack-ul rezultat, deși nu este banal, în realitate este destul de simplu. Adăugarea PhantomJS la capătul seleniului ne permite să începem să folosim Selenium fără o investiție inițială prea mare, cum ar fi instalarea de servere de testare grafice.

Utilizarea JavaScript ca motor de testare asigură faptul că testele noastre vor fi ținute relevante în contextul dezvoltării web pentru viitorul apropiat.

Cod