Teste JavaScript și automatizarea acestora. Test de cunoștințe JavaScript - Noțiuni de bază Testarea codului javascript

Testarea codului este un ciclu integral al dezvoltării software. Echipele de dezvoltare începătoare subestimează adesea rolul său și verifică funcționalitatea aplicației în mod vechi - „funcționează, bine”. Mai devreme sau mai târziu, această strategie eșuează și dispozitivul de urmărire a erorilor începe să fie copleșit de o armată nenumărate de sarcini. Pentru a evita căderea într-o astfel de capcană, recomand o dată pentru totdeauna să înțelegeți nuanțele testării codului JavaScript.

JavaScript nu mai este la fel

Astăzi, JavaScript este mai mult decât un simplu limbaj pentru a condimenta aspectul unei aplicații. Vremurile în care JavaScript era folosit pentru glume sau pentru a face meniuri au dispărut irevocabil. Acum este un limbaj independent care funcționează la fel de bine atât pe client, cât și pe server. Rolul JavaScript a crescut semnificativ, ceea ce înseamnă că atunci când scrieți cod nu trebuie să vă sfiați să folosiți practici care s-au dovedit în alte limbaje de programare.

Ce înțeleg prin practici și paradigme? Desigur, modelul arhitectural MVC (model view controller) și modelele de organizare a codului. Urmând aceste trucuri simple, veți putea scrie un cod mai bun care nu numai că va fi ușor de întreținut, dar va avea și capacitatea de a fi testat automat.

Greșeală a majorității testerilor

Nu este un secret pentru nimeni că cea mai populară metodă de testare a fost întotdeauna un test banal al ochilor. Esența sa este simplă până la disgrație - scrieți câteva mii de linii de cod, rezolvați problema și lansați creația. M-am jucat, am dat clic, totul pare să funcționeze, îl puteți încărca pe serverul de producție. Totul este extrem de simplu și cu atenția cuvenită din partea dezvoltatorului (în mod ideal, o persoană separată poreclit „tester”), vă puteți baza pe funcționarea corectă a aplicației.

În practică, totul se întâmplă puțin diferit. De regulă, nu există un tester separat. Dezvoltatorul însuși încearcă să verifice funcționalitatea programului prin efectuarea secvenței de acțiuni specificate în specificațiile tehnice. Forțele de cod mai avansate automatizează acest tip de testare de integrare folosind lucruri precum Selenium.

Astfel, programatorul are posibilitatea de a detecta doar cele mai grave erori. Din păcate, acțiunile „prostice” și „neintenționate” ale utilizatorului, precum și mișcările viclene în logica afacerii, rămân în spatele scenei în 99% din cazuri.

Prezența unei persoane separate în persoana unui tester rezolvă, de asemenea, problema parțial și până la un anumit timp. Chiar dacă ignorăm atenția saperului său pentru detalii, calitatea testării sale va tinde să scadă la zero pe măsură ce aplicația crește. Permiteți-mi să vă dau un exemplu din practică.

Într-o zi am fost desemnat să dezvolt un mic program. Din punct de vedere al funcționalității, proiectul semăna cu un simplu CRM, pe care l-am implementat în cel mai scurt timp posibil. După ce am primit remunerația cuvenită, am predat toate sursele clientului și am uitat de proiect timp de opt luni. Apoi a început distracția. Clientul a decis să extindă serios funcționalitatea programului și m-a sunat pentru ajutor. Firește, l-am luat și am început să sculpt o nouă funcție după funcție. La început nu a fost dificil, dar când a fost vorba de integrarea generală a funcționalității, un roi de bug-uri s-a repezit în direcția mea. Bucăți de cod au început să intre în conflict și a trebuit să petrecem mult timp rezolvând conflictele. „Ei bine, cum de nu ați văzut că au existat probleme cu aplicația dvs.?” - vor întreba cititorii atenți. L-am lansat, dar din cauza faptului că aplicația a crescut, pur și simplu nu am avut suficient timp și nervi să testez în masă toată funcționalitatea. M-am limitat la a testa doar funcții individuale și am plătit frumos pentru asta. Morala poveștii este „Gândește-te la testare ca parte integrantă a dezvoltării”.

Testele unitare sunt ca un glonț de argint

Testarea unitară este cea mai bună modalitate de a vă salva nervii și de a crește garanțiile privind performanța părților individuale ale aplicației. Dacă nu ați întâlnit niciodată acest cuvânt groaznic, atunci vă voi explica pe scurt. Testele unitare vă permit să automatizați procesul de testare și să testați fiecare caracteristică a aplicației dvs.

După finalizarea dezvoltării unei noi funcții (este posibil să se scrie teste înainte de începerea dezvoltării), dezvoltatorul scrie cod special pentru a-și testa codul. În codul de testare, trebuie să simulați diferite situații și să returnați valori. De exemplu, am scris o funcție pentru a tăia spațiile (decupați). Pentru a-i testa performanța, trebuie să pregătim mai multe teste care ne vor permite să afirmăm că:

  • la trecerea șirului "șir" vom obține "șir" ca ieșire;
  • la transmiterea termenilor „linia 9”, vom primi „linia 9” la ieșire;
  • Putem adăuga și testare pentru alți parametri de intrare (de exemplu, înlocuirea caracterului spațiu cu o tabulatură). În general, cu cât acoperim mai bine codul cu teste și oferim posibile opțiuni negative, cu atât este mai mare șansa ca în momentul cel mai crucial să rămână puțin păr pe cap.

    În lumea JS, testele sunt de obicei scrise folosind cadre specializate. Au tot ce ai nevoie pentru a descrie testele, precum și cel puțin câteva instrumente pentru sistematizarea rapoartelor de progres ale testelor.

    Teste!= cod suplimentar

    Dezvoltatorii care nu folosesc testarea unitară le place să susțină că testarea unitară necesită scrierea și menținerea codului suplimentar. Ei spun că termenele limită în proiectele reale sunt adesea strânse și pur și simplu nu este posibil să scrieți cod suplimentar.

    Sunt de acord cu termenele limită strânse, dar sunt dispus să argumentez despre codul suplimentar. Pe de o parte, da, testele necesită cod suplimentar și, prin urmare, timp pentru a-l scrie. Pe de altă parte, acest cod joacă rolul airbag-urilor într-o mașină și cu siguranță se va plăti singur pe măsură ce aplicația crește.

    Când nu ai timp și ești chinuit de dorința de a renunța la testele scrise, gândește-te de trei ori. În acest caz, poate fi mai potrivit să acoperiți doar cele mai complicate secțiuni ale codului cu teste, decât să abandonați complet testarea. Gândește-te întotdeauna cu ochiul spre viitor, ca și cum într-o lună programul tău poate crește la proporții fără precedent.

    Nu orice cod este testat

    De ce spun că trebuie să vă gândiți la testare înainte de a scrie codul principal? Da, pentru că codul care inițial ar trebui să fie acoperit de testele unitare este scris într-un stil ușor diferit. Nu orice cod poate fi testat. Cod care combină logica și reprezentările și este, de asemenea, înghesuit în zone în care este imposibil de testat corespunzător. Aici vă sfătuiesc întotdeauna să urmați câteva reguli simple:

  • Nu este nevoie să scrieți funcții mari. Fiecare funcție ar trebui să rezolve o problemă, nu 100.500 de situații posibile. De exemplu, nu este nevoie să introduceți codul pentru trimiterea datelor către server în funcția responsabilă cu pregătirea acestuia;
  • O funcție care constă din mai mult de 10 linii de cod este cel mai probabil o funcție proastă;
  • Logica și prezentarea nu ar trebui să meargă niciodată împreună;
  • QUnit - un clasic de la creatorii jQuery

    QUnit este deosebit de popular printre dezvoltatorii JavaScript. În primul rând, este bine documentat și ușor de utilizat, iar în al doilea rând, a fost creat de autorii jQuery. Biblioteca este potrivită pentru testarea codului JavaScript bazat pe jQuery și nativ.

    Puteți descărca cea mai recentă versiune a QUnit de pe site-ul oficial - http://qunitjs.com/. Biblioteca vine ca un singur fișier JS și CSS. Să presupunem că v-ați dat seama că încărcați componentele necesare și, dacă da, atunci este timpul să scrieți un test de probă. Să nu mergem departe și să încercăm să testăm funcția trim() menționată mai sus.

    Pentru a demonstra testele, am creat un proiect simplu cu următorul constructor:

    Index.html – fișierul principal care va afișa rezultatele testelor; - qunit-1.12.0.js – fișier bibliotecă qunit; - example.js – fișier care conține cod pentru testare (în cazul nostru, o descriere a funcției trim()); - test.js – fișier cu teste; - qunit-1.12.0.css – stiluri de proiectare a unui raport cu teste;

    Conținutul fișierelor index.html și test.js este prezentat în listele 1 și 2. Ne interesează cel mai mult a doua listă, care conține declarația funcției testate (trim()) și codul de testare pentru verificarea acesteia. funcţionalitate. Vă rugăm să rețineți că funcția trim() în sine poate fi localizată oriunde am pus-o în a doua listă doar pentru a economisi spațiu în revistă.

    Acum să ne uităm la testele în sine. Pentru a verifica funcționalitatea codului nostru, biblioteca Qunit.js ne oferă o serie de metode:

  • test() – wrapper pentru descrierea testului;
  • ok() – afirmația vă permite să verificați adevărul primului parametru. În exemplul nostru, îi transmit un apel către funcția trim() pe care am definit-o și o compar cu valoarea pe care mă aștept să o primesc. Dacă condiția este adevărată, testul este trecut;
  • equal() – metoda vă permite să verificați egalitatea primului și celui de-al doilea parametru. Vă rugăm să rețineți imediat că această metodă efectuează o verificare slabă, deci este potrivită doar pentru cantități scalare;
  • notEqual() este opusul egal(). Se execută dacă prima valoare nu este egală cu a doua;
  • strictEqual() este similar cu equal() cu o diferență - folosește verificarea strictă (adică verifică și tipul de date);
  • notStrictEqual() – metoda este opusul strictEqual();
  • deepEqual() – metodă pentru aserțiuni recursive, folosită pentru primitive, matrice, obiecte;
  • notDeepEqual() – metoda este opusul deepEqual();
  • raises() – o instrucțiune pentru testarea funcțiilor de apel invers care aruncă o excepție;
  • În a doua listă, am arătat clar cum să aplic aceste metode în practică. Dacă rulați exemplul de testare în acest formular, atunci toate testele vor trece cu succes (a se vedea figura corespunzătoare). Pentru a vedea diferența dintre testele care au trecut și cele care au eșuat, am modificat ușor codul pentru un test. Am adăugat în mod deliberat un rezultat eronat la linia de test folosind strictEqual() (a se vedea figura corespunzătoare).

    Listarea 1. Conținutul fișierului index.html Testarea cu QUnit Listarea 2. Fișierele de testare și funcția trim() trim(string) ( return (șir || "").replace(/^\s+|\s+$/g, ""); ) test("Testează funcția trim()", function() ( ok(trim(" test ") == "test", "tăiați spațiile"); ok(trim(" 1 ") == „1”, „multe spații pe laturi”); , "Linie goală" "); strictEqual(trim(" ][aker") ));

    Se pare că am rezolvat testarea funcțiilor simple. În orice caz, nu mai am nimic de adăugat. Apoi, trebuie să luați cod real și să încercați să scrieți singur teste. Să ne uităm la o altă sarcină frecvent întâlnită pentru dezvoltatorii JavaScript - testarea funcțiilor asincrone. O aplicație plină cu cod JavaScript interacționează 99% cu partea de server folosind Ajax. Nici acest cod nu poți lăsa nebifat, dar scrierea testelor va arăta puțin diferit. Să ne uităm la un exemplu:

    AsyncTest("myAsyncFunc()", function() ( setTimeout(function() ( ok(myAsyncFunc() == true, "Date transferate cu succes"); start(); ), 500); ));

    Principala diferență dintre acest exemplu și cel precedent este că în loc de wrapper-ul test() este folosit asyncTest(), declarând astfel direct că sunt interesat să testez în mod specific testarea asincronă. In continuare incep timpul de asteptare la 500 ml. sec. În acest timp, funcția myAsyncFunc() ar trebui să transfere date pe serverul de testare și, dacă totul este bine, să returneze true. Aici vine cel mai interesant moment. Când asyncTest() este apelat, firul de execuție se oprește și când testul este finalizat, acesta trebuie lansat independent. Pentru a controla fluxul de execuție, QUnit are metode start() și stop().

    Testarea funcțiilor asincrone folosind biblioteca QUnit este destul de simplă. Ultimul exemplu pe care aș dori să mă uit implică scrierea unui test care efectuează mai multe verificări asincrone. Principala întrebare care apare în astfel de sarcini este locul optim pentru a începe firul de execuție. Documentul oficial sugerează utilizarea a ceva de genul:

    AsyncTest("myAsyncFunc()", function() ( asteptam(3); //Aici facem trei verificări ok(myAsyncFunc(), "Making the world a better place 1"); ok(myAsyncFunc(), "Making the lume un loc mai bun 2" ); ok(myAsyncFunc(), "Faking the world a better place 3"); setTimeout(function() (start(); ));

    Testați pentru acțiuni personalizate

    Ar trebui să vă amintiți întotdeauna că multe lucruri de interfață sunt scrise în JavaScript. De exemplu, un utilizator face clic pe un proxenet și ar trebui să se întâmple ceva ca răspuns la clicul său. Există o cantitate imensă de astfel de cod de „interfață” în proiecte și, de asemenea, trebuie acoperit cu teste. Să vedem cum putem simula apăsarea tastei unui utilizator și să scriem un test separat pentru această acțiune. Să ne imaginăm că avem o anumită funcție care înregistrează tastele apăsate. Am furnizat codul său în a treia listă:

    Lista 3. Funcția de înregistrare a tastelor KeyLogger(țintă) ( if (!(această instanță a KeyLogger)) ( returnează un nou KeyLogger(țintă); ) this.target = target; this.log = ; var self = this; this.target. off ("keydown").on("keydown", function(eveniment) ( self.log.push(event.keyCode); ));

    Acum să încercăm să testăm această funcție. În primul rând, în corpul testului trebuie să emulăm tasta apăsată. Cel mai simplu mod de a face acest lucru este folosirea bibliotecii jQuery, care vă permite să creați un eveniment în câteva linii de cod (vezi Lista 4).

    Lista 4. Cod de testare pentru testul KeyLogger("Test de înregistrare a tastelor", function() (var eveniment, $doc = $(document), chei = KeyLogger($doc); event = $.Event("keydown"); eveniment .keyCode = 9; $doc.trigger(equal(keys.log.length, 1, "Key recorded" (keys.log[ ], 9, "Tasta apăsată cu codul 9"); );

    Chiar la începutul listei de testare, pregătesc un eveniment pentru a emula o apăsare de tastă - „keydown”. Vom fi interesați să apăsăm tasta Tab (cod 9). Apoi, folosind metoda trigger(), trimit evenimentul pregătit, după care pot începe testarea. În primul rând, verificăm imaginea de ansamblu - dacă o tastă a fost apăsată și apoi codul acesteia.

    DOM sub masca testelor

    Deoarece Qunit.js vă permite să testați acțiunile utilizatorului, nici scrierea de teste pentru DOM nu ar trebui să fie o problemă. Acest lucru este într-adevăr adevărat și exemplul de mai jos îmi va confirma cuvintele. Nu o să comentez, doar uită-te la cod și totul va deveni clar:

    Test("Adăugați un nou element div", function() ( var $fixture = $("#qunit-fixture"); $fixture.append("Acesta este un nou div"); equal($("div", $fixture) .length, 1, "Div nou adăugat cu succes!");

    Phantom.JS – rulează teste de pe consolă

    Scrierea de teste folosind biblioteca Qunit.js este convenabilă și simplă, dar mai devreme sau mai târziu veți avea dorința de a automatiza cumva lansarea testării și colectarea rezultatelor. De exemplu, în acest scop am o mașină virtuală separată în DigitalOcean, pe care o pot gestiona doar folosind consola.

    Proiectul phantom.js rezolvă această problemă destul de elegant. Acesta nu este un alt cadru pentru scrierea testelor unitare, ci o versiune de consolă cu drepturi depline a motorului WebKit. Pentru a spune simplu, această aplicație emulează un browser. Cu ajutorul phantom.js, este posibilă nu numai automatizarea verificării execuției testului, ci și rezolvarea multor probleme care mai devreme sau mai târziu apar în fața unui dezvoltator: obținerea rezultatelor randării paginii într-un fișier (png, jpg), rețea funcții de monitorizare (viteza de încărcare, performanța generală etc.), emularea acțiunilor utilizatorului etc. Vă recomand să vă faceți timp și să citiți documentația oficială despre acest proiect, cu siguranță veți găsi ceva interesant pentru dvs.

    Phantom.js poate fi compilat pentru diferite platforme (nix, mac OS X, windows). Dacă dezvoltați totul pe Windows, atunci nu există probleme - îmbinați fișierele binare și mergeți mai departe. Pot apărea probleme minore la pornire dacă aveți două adaptoare video instalate, dintre care unul este NVidia. În acest caz, va trebui să utilizați hack-ul descris în bara laterală.

    Să încercăm să ne familiarizăm cu phantom.js în practică. Pentru a rula testele pregătite în ultima secțiune prin phantom.js și pentru a obține rezultatele execuției în consolă, avem nevoie de un script de încărcare special - run-qunit.js. Deschide consola (lucrez pe Windows, deci folosesc cmd) și tastați comanda în formatul:

    Phantom.exe

    În cazul meu, comanda de lansare arăta astfel:

    E:\soft\phantomjs>phantomjs.exe E:\temp\testjsforx\qunit\run-qunit.js file:///E: /temp/testjsforx/qunit/index.html Rezultatul executării acestuia: Teste finalizate în 2592 milisecunde. 9 afirmații din 9 au trecut, 0 au eșuat.

    Toate testele au trecut

    Este cu siguranță necesar să vă acoperiți codul cu teste, indiferent de scara aplicației pe care o creați. Încă o dată, vă reamintesc că și cele mai mici programe se transformă în monștri stângaci care au nevoie de suport și funcționalitate adăugată. Codul bine testat este cheia succesului și calității. Da, nu este ușor să începeți imediat să scrieți cod potrivit pentru testele automate, dar credeți-mă, tot acest chin va plăti mai mult decât în ​​viitor. Asta e tot pentru azi, succes!

    Când nu există timp pentru teste

    Dacă nu aveți timp, nu are rost să scrieți teste pentru funcții simple (luați același trim() din exemplele din articol, este mai bine să vă concentrați pe cele mai critice secțiuni ale codului). Aceeași regulă trebuie urmată atunci când scrieți codul schimbat frecvent. Specificațiile tehnice ale unui proiect live se modifică frecvent, iar unele funcții trebuie actualizate constant. Astfel de modificări pot duce la momente neplăcute - codul modificat funcționează bine cu date noi, dar nu digeră organic datele vechi. Deci, pentru a nu prinde un eșec aici, este mai bine să acoperiți imediat astfel de funcții cu teste. Amintiți-vă de o regulă simplă - nu există timp pentru a acoperi întregul cod cu teste, acoperiți cea mai importantă parte a acestuia.

    Reguli pentru teste bune
  • Testul ar trebui să fie cât se poate de simplu. Cu cât testul este mai complex, cu atât este mai probabil să facă greșeli;
  • Testele trebuie grupate în module pentru a facilita găsirea erorilor mai târziu și pentru a putea testa anumite părți ale aplicației;
  • Fiecare test ar trebui să fie independent de alte teste;
  • Scrieți întotdeauna un test separat de fiecare dată când găsiți erori;
  • probleme phantom.js pe Windows

    Așa s-a întâmplat, dar am testat toate exemplele din acest articol nu pe Linux, ci pe un vechi Windows 7. Se pare că phantom.js are probleme minore când lucrează pe sisteme care folosesc mai multe adaptoare video. Pe lângă cipul video integrat, laptopul meu are și NVidia și din cauza phantom.js a refuzat categoric să răspundă la comanda phantom.exit(). Drept urmare, după executarea scriptului, procesul phantom.js nu și-a finalizat activitatea și a continuat să se blocheze în memorie. De asemenea, fereastra terminalului nu mai răspunde la comenzile de închidere (ctrl + c nu a ajutat).

    Dacă vă confruntați cu o problemă similară și intenționați să utilizați phantom.js pe Windows, atunci pregătiți-vă să faceți următorul hack. Deschide Panoul de control Nvidia. Găsiți elementul „Setări 3D” în arbore. Opțiunea „Adaptor grafic preferat” ar trebui să apară în partea dreaptă. În mod implicit, valoarea sa este setată la „Selectare automată”. Trebuie să-l schimbăm în „Procesor Nvidia de înaltă performanță” sau „Hardware grafic integrat”. După acest truc simplu, phantom.js a început să se comporte ascultător.

  • „Test-Driven JavaScript Development” a lui Cristian Johansen este una dintre puținele cărți care privește JavaScript din punctul de vedere al scrierii de teste;
  • John Resing, Beer Bibo „Secretele Ninja JavaScript” este o carte bună, care va fi utilă în primul rând pentru dezvoltatorii JS cu un nivel mediu de pregătire. Cartea discută în detaliu problemele scrierii unui cod eficient între browsere, nuanțele procesării evenimentelor și multe alte bunătăți.
  • Și este instrumentul oficial de testare jQuery. Dar QUnit este excelent pentru a testa orice cod JavaScript și poate chiar testa backend-ul JavaScript folosind motoare precum Rhino sau V8.

    Dacă nu sunteți familiarizat cu ideea de „testare unitară”, nu vă faceți griji - nu este nimic complicat:

    „Testarea unitară sau testarea unitară (engleză) testarea unitară) este un proces de programare care vă permite să verificați corectitudinea modulelor individuale ale codului sursă al unui program. Ideea este de a scrie teste pentru fiecare funcție sau metodă non-trivială. Acest lucru vă permite să verificați rapid dacă următoarea modificare a codului a dus la regresie, adică la apariția erorilor în locurile deja testate ale programului și, de asemenea, facilitează detectarea și eliminarea unor astfel de erori."

    Definiție citată din Wikipedia. Faceți doar teste pentru fiecare bloc funcțional al codului dvs. și, dacă toate testele trec, puteți fi sigur că nu există erori (depinde în principal de cât de atent sunt proiectate testele).

    De ce ar trebui să vă testați codul

    Dacă nu ați mai scris niciodată teste unitare, probabil că ați găzduit codul direct pe un server web, l-ați rulat, ați urmărit erorile și ați încercat să le remediați pe măsură ce au fost găsite. Această metodă de lucru dă naștere la multe probleme.

    În primul rând, aceasta este o activitate foarte plictisitoare și plictisitoare. Validarea este de fapt o muncă destul de dificilă, deoarece trebuie să fii sigur că totul a fost presat. Și în acest proces există o probabilitate foarte mare ca unul sau două puncte să fie ratate.

    În al doilea rând, tot ceea ce se face pentru astfel de testare nu poate fi reutilizat. Cu această metodă este foarte greu de găsit regresii. Ce sunt regresiile? Imaginați-vă că ați scris un cod și l-ați testat, ați reparat toate erorile găsite și ați plasat codul pe site. Apoi utilizatorul a trimis feedback despre erori noi și o solicitare pentru noi funcții. Reveniți la cod, remediați erorile și adăugați funcții noi. În acest caz, poate apărea o situație în care erorile vechi apar din nou, ceea ce se numește „regresie”. Trebuie să verificați totul din nou. Și există șansa să nu-ți găsești vechile greșeli. În orice caz, va dura timp până când îți dai seama că problema este cauzată de o „regresie”. Când utilizați testarea unitară, scrieți un test. Odată ce codul este modificat, îl filtrezi din nou prin test. Dacă apare regresia, atunci unele teste vor eșua și puteți determina cu ușurință care parte a codului conține eroarea. Deoarece știți ce ați schimbat, eroarea va fi ușor de remediat.

    Un alt avantaj al testării unitare (în special pentru dezvoltarea web) este că este ușor de testat compatibilitatea între browsere. Trebuie doar să rulați teste în diferite browsere. Dacă se găsesc probleme în browser, le puteți remedia și executa din nou testul. Ca rezultat, veți fi sigur că toate browserele țintă sunt acceptate, deoarece toate au fost testate.

    Cum se scrie teste unitare în QUnit

    Deci, cum scrieți direct teste unitare în QUnit? Primul pas este instalarea mediului de testare:

    QUnit Test Suite QUnit Test Suite

    Codul care va fi testat intră în fișierul myProject.js, iar testele intră în myTests.js. Pentru a rula testele, trebuie doar să deschideți fișierul HTML în browser. Acum este timpul să scriem un test.

    Elementul de bază al testării unitare este afirmația.

    „O aserțiune este o expresie care prezice rezultatul returnat atunci când codul tău este executat. Dacă predicția este incorectă, atunci aserția are o valoare fals, ceea ce ne permite să tragem concluzii despre prezența erorilor.”

    Pentru a executa aserțiuni, acestea trebuie să fie plasate într-un bloc de testare:

    // testează această funcție funcție isEven(val) ( return val % 2 === 0; ) test("isEven()", function() ( ok(isEven(0), "Zero este un număr par"); ok ( isEven(2), „Doi este, de asemenea,” ok(isEven(-4), „Și negativ patru este, de asemenea, un număr par”); isEven(-7), „Ca și negativul șapte este un număr impar”);

    Aici definim o funcție este Par, care verifică paritatea unui număr și dorim să ne asigurăm că această funcție nu returnează valori eronate.

    Mai întâi numim funcția test(), care construiește un bloc de testare. Primul parametru este șirul care va fi scos ca rezultat. Al doilea parametru este o funcție de returnare care conține afirmațiile noastre. Această funcție de apel invers va fi apelată o dată în timpul execuției QUnit.

    Am scris cinci afirmații, toate logice. Declarația logică presupune că primul parametru are o valoare adevărat. Al doilea parametru este mesajul care este afișat în rezultat.

    Iată ce obținem după rularea testului:

    Toate afirmațiile noastre au fost confirmate cu succes, așa că putem presupune că funcția isEven() functioneaza conform asteptarilor.

    Să vedem ce se întâmplă dacă afirmația este falsă.

    // testează această funcție funcție isEven(val) ( return val % 2 === 0; ) test("isEven()", function() ( ok(isEven(0), "Zero este un număr par"); ok ( isEven(2), „Doi este, de asemenea,” ok(isEven(-4), „Și negativ patru este, de asemenea, un număr par”); isEven(-7), "Ca și negativul șapte este un număr impar" // Eroare ok(isEven(3), "Trei este un număr par");

    Și asta este ceea ce obținem ca rezultat al rulării testului:


    Declarația conține o eroare pe care am făcut-o în mod intenționat. Dar în proiectul dvs., dacă un test eșuează și toate celelalte afirmații sunt corecte, atunci va fi foarte ușor să găsiți eroarea.

    Alte afirmatii

    ok() nu este singura declarație pe care o acceptă QUnit. Există și alte tipuri de aserțiuni care sunt utile pentru a fi utilizate atunci când scrieți teste pentru proiectele dvs.:

    Declarație de comparație

    Declarație de comparație este egal() presupune că primul parametru (care este valoarea reală) este echivalent cu al doilea parametru (care este valoarea așteptată). Această afirmație este foarte asemănătoare cu Bine(), dar emite atât valori reale, cât și valori așteptate, ceea ce face depanarea codului mult mai ușoară. Exact ca Bine(), este egal() poate accepta un mesaj pentru ieșire ca al treilea parametru.

    Deci in schimb

    Test(„aserțiuni”, funcția() (ok(1 == 1, „unul este echivalent cu unul”); ))


    Ar trebui folosit:

    Test(„aserțiuni”, funcția() (egal(1, 1, „unul este echivalent cu unul”); ))


    Rețineți că valoarea așteptată este tipărită la sfârșitul rândului.

    Și dacă valorile nu sunt egale:

    Test(„aserțiuni”, funcția() (egal(2, 1, „unul este echivalent cu unul”); ))


    Această intrare oferă mai multe informații.

    Afirmația de comparație folosește operatorul „==” pentru a testa parametrii, deci nu poate funcționa cu matrice sau obiecte:

    Test("test", function() (egal((), (), "eroare, acestea sunt obiecte diferite"); equals((a: 1), (a: 1) , "eroare"); egal(, , „eroare, acestea sunt matrice diferite”;

    Pentru astfel de cazuri, QUnit are o afirmație de identitate.

    Afirmarea identității

    Afirmarea identității aceleaşi() folosește aceiași parametri ca este egal(), dar funcționează nu numai cu tipurile primitive, ci și cu matrice și obiecte. Declarațiile din exemplul anterior vor trece testul dacă sunt modificate de la declarații de identitate:

    Test("test", function() (același((), (), "trece, obiectele au același conținut"); same((a: 1), (a: 1) , "trece"); același( , , "trece, tablourile au același conținut"; same(, , "trece");

    Vă rugăm să rețineți că aceleaşi() folosește operatorul „===” pentru comparare, deci este convenabil să se utilizeze pentru compararea valorilor speciale:

    Test(„test”, funcția() (egal(0, fals, „adevărat”); același(0, fals, „fals”); egal(null, nedefinit, „adevărat”); același(null, nedefinit, „ fals"); ))

    Structura declarației

    Plasarea tuturor afirmațiilor într-un singur test este o idee foarte proastă. Un astfel de test va fi dificil de întreținut și puteți deveni confuz în evaluarea rezultatelor executării sale. Prin urmare, trebuie să structurați testul prin plasarea instrucțiunilor în blocuri separate, fiecare dintre acestea având ca scop un anumit grup de funcții.

    Puteți organiza module individuale folosind un apel de funcție modul:

    Modul ("Modulul A"); test("Test", function() ()); test("Un alt test", function() ()); module ("Modulul B"); test("Test", function() ()); test("Un alt test", function() ());


    În exemplul anterior, toate instrucțiunile au fost apelate sincron, adică au fost executate una după alta. Există multe funcții asincrone în lumea reală, cum ar fi cereri sau funcții AJAX setTimeout()Şi setInterval(). Cum testăm acest tip de funcționalitate? QUnit are un tip de test special numit „test asincron”, care este conceput pentru testarea asincronă:

    Mai întâi, să încercăm să scriem un test în modul obișnuit:

    Test(„Test asincron”, function() ( setTimeout(function() (ok(true); ), 100) ))


    Se pare că nu există afirmații în test. Deoarece instrucțiunea a fost executată sincron, dar în momentul în care funcția a fost apelată, testul fusese deja finalizat.

    Modul corect de a testa exemplul nostru este:

    Test("Test asincron", function() ( // Pune testul in modul pauza stop(); setTimeout(function() ( ok(true); // Dupa apelarea afirmatiei // continua test start(); ) , 100) ))


    Am folosit funcția Stop() pentru a opri testul, iar după executarea aserției, rulați din nou testul folosind funcția început().

    Apelarea unei funcții Stop() imediat după apelarea funcției test() este o practică foarte comună. De aceea QUnit are o abreviere specială: asyncTest(). Exemplul anterior poate fi rescris astfel:

    AsyncTest(„Test asincron”, function() ( // Testul este comutat automat în modul „pauză” setTimeout(function() ( ok(adevărat); // După apelarea aserției // continuă începerea testului(); ) , 100) ))

    Există un punct la care merită să ne gândim: funcția setTimeout()își apelează întotdeauna funcția de apel invers și dacă testează o altă funcție (de exemplu, un apel AJAX). Cum poți fi sigur că va fi apelată funcția de apel invers? Dacă funcția de returnare nu este apelată, funcția început() va rămâne, de asemenea, neapelat și întregul test va îngheța:


    Puteți organiza testul astfel:

    // Funcția personalizată a funcției ajax(successCallback) ( $.ajax(( url: "server.php", succes: successCallback )); ) test("Test asincron", function() ( // Opriți testul și // raportați o eroare dacă funcția start() nu este apelată după 1 secundă stop(1000 ajax(function() ( // ...instrucțiunea asincronă start(); )) ));

    Sa functioneze Stop() se transmite valoarea timeout. Acum QUnit i se spune: „dacă funcția început() nu va fi apelat după expirarea timpului de expirare, acest test ar trebui considerat eșuat.” Acum întregul test nu va îngheța și va fi emis un avertisment dacă ceva nu merge bine.

    Acum luați în considerare cazul mai multor funcții asincrone. Unde să plasați funcția început()? Trebuie să-l plasați într-o funcție setTimeout():

    // Funcția personalizată a funcției ajax(successCallback) ( $.ajax(( url: "server.php", succes: successCallback )); ) test("Test asincron", function() ( // Oprește testul stop(); ajax (function() ( // ...instrucțiune asincronă )) ajax(funcție() ( // ...instrucțiune asincronă )) setTimeout(function() ( start(); ), 2000 ));

    Valoarea de expirare trebuie să fie suficientă pentru a permite finalizarea ambelor apeluri înapoi înainte ca testul să continue. Dacă una dintre funcții nu este numită, cum putem determina care? Există o funcție pentru asta aştepta():

    // Funcție personalizată ajax(successCallback) ( $.ajax(( url: "server.php", succes: successCallback )); ) test("Test asincron", function() ( // Opriți testul stop(); // Spune-i lui QUnit că ne așteptăm să fie executate trei instrucțiuni expect(3); function( ) ( start(); ), 2000 ))

    Trecem la functie aştepta() numărul de instrucțiuni care sunt planificate a fi executate. Dacă una dintre declarații eșuează, veți primi un mesaj care vă indică faptul că ceva nu merge conform planului.

    Există o scurtă înregistrare pe care o puteți utiliza aştepta(): trebuie să treceți numărul de instrucțiuni programate ca al doilea parametru test() sau asyncTest():

    // Funcția funcție personalizată ajax(successCallback) ( $.ajax(( url: "server.php", succes: successCallback )); ) // Spune-i lui QUnit că ne așteptăm să fie executate 3 instrucțiuni test("test asincron", 3 , function() ( // Opreste testul stop(); ajax(function() ( ok(true); )) ajax(function() ( ok(true); ok(true); )) setTimeout(function() ( începutul (); 2000);

    Concluzie

    În acest tutorial am furnizat tot ce aveți nevoie pentru a începe cu QUnit. Testarea unitară este o metodă excelentă pentru testarea codului înainte de a-l folosi. Dacă nu ați mai folosit niciodată teste, acum este momentul să începeți.

    Testarea pentru cunoașterea următoarelor subiecte este acum disponibilă pe site: HTML, CSS, JavaScript, PHP, SQL.

    Fiecare test constă din 10 întrebări pe o anumită temă. În fiecare întrebare, am încercat să acopăr cele mai diverse domenii de aplicare a unei anumite limbi pentru a vă testa cât mai bine nivelul de cunoștințe.

    Desigur, toate testele sunt gratuite și oricine le poate susține.

    Procedura de testare:

  • Urmați linkul „Începe testarea” pentru testul corespunzător.
  • Răspundeți la întrebările puse alegând singura opțiune corectă.
  • La finalizarea testului, veți vedea scorul dvs., numărul de erori, precum și o analiză a fiecărei întrebări din test.
  • Atenţie! Nu vă veți putea întoarce la întrebarea anterioară, așa că gândiți-vă înainte de a răspunde.

    Teste disponibile momentan
  • HTML
    • Total test efectuat: 75.424 de persoane
    • Scor mediu: 2,83 din 5 puncte.

    Test de bază HTML. Veți avea nevoie de cunoștințe despre etichetele HTML de bază, precum și despre utilizarea lor competentă. De asemenea, este necesar să înțelegeți caracteristicile standardului XHTML 1.1.

  • CSS
    • Total test efectuat: 32828 persoane
    • Scor mediu: 3,37 din 5 puncte.

    Testul testează cunoștințele de bază ale CSS. Pentru a trece cu succes testul, trebuie să cunoașteți principalele tipuri de selectoare (sintaxa acestora), să cunoașteți proprietățile de bază și valorile posibile ale acestora și, de asemenea, să cunoașteți scopul celor mai populare pseudo-elemente.

  • JavaScript
    • Total test efectuat: 24845 persoane
    • Scor mediu: 3,31 din 5 puncte.

    Acest test vă testează cunoștințele despre limbajul JavaScript. Întrebările testului acoperă diferite domenii de aplicare a acestui limbaj. Există o mulțime de întrebări despre înțelegerea nuanțelor „mici”. În caz contrar, vi se cere să cunoașteți lucruri de bază: lucrul cu variabile, funcții JavaScript de bază, priorități de operare etc.

  • PHP
    • Total test efectuat: 33.239 de persoane
    • Scor mediu: 3,03 din 5 puncte.

    Acest test vă testează cunoștințele despre limbajul PHP. Vi se cere să cunoașteți constructele PHP de bază, să lucrați cu variabile, sesiuni, să implementați redirecționări și alte lucruri standard.
    Vă rugăm: Testul conține multe întrebări precum: „Ce va afișa scriptul?” Vă rugăm să nu-l copiați sau verificați. Fii sincer cu tine însuți.

  • SQL
    • Total test efectuat: 18.014 persoane
    • Scor mediu: 3,28 din 5 puncte.

    Acest test vă testează cunoștințele despre limbajul de interogare SQL. Întrebările acoperă doar cele mai elementare cunoștințe ale acestei limbi, fără nicio profunzime. Veți avea nevoie de cunoștințe despre cele mai elementare interogări SQL, precum și despre utilizarea lor competentă.