Aplicatie Catalog Facultate

Introducere

În zilele noastre sunt foarte multe firme care produc produse software. Concurența dintre ele este foarte mare și orice detaliu cât de mic poate face diferența. Din această cauză, acestea pun un foarte mare accent pe calitatea produselor lor și sunt conștiente că un produs de proastă calitate ar putea însemna pierderea iremediabilă a actualilor și potențialilor clienți.

Testarea software este principalul mijloc de asigurare a calității produsului software. Managementul procesului de testare este deosebit de important. Acesta poate defini eșecul sau succesul unui produs software.

Presiunea timpului și bugetului alocat produsului software are, nu de puține ori, un impact negativ asupra calității produsului. În ajutorul acestor probleme vin o mulțime de instrumente de management care ajută la gestionarea eficientă a procesului de testare.

În general problemele legate de calitatea software sunt determinate de cerințele definite incomplet (50% din cazuri), modelarea neclară sau insuficientă a acestora (30% din cazuri) și de erorile de programare (20% din cazuri).

Costurile erorilor depistate și fixate în faza de descriere a specificațiilor nu costă practic nimic. În schimb, erorile depistate după livrarea produsului măresc costul acestora substanțial.

Metodologiile moderne, precum Agile, extreme Programming, Scrum etc. pun accentul pe procesul de testare și îl integrează în profunzime cu celelalte activități care țin de dezvoltarea programelor software: planificare, proiectare, programare, evaluare și control.

Am ales acesta temă deoarece am văzut importanța acestui proces și impactul pe care îl are testarea asupra unui proiect la locul de muncă.

Această lucrare iși propune să detalieze tipurile de testare și de teste, tehnologiile și uneltele actuale de testare precum și modurile în care poate fi organizat procesul de testare al unui proiect și cele mai bune practici din domeniu. Toate acestea vor fi exemplificate pe baza aplicației „Catalog facultate”, o aplicație web care permite gestionarea și vizualizarea notelor studenților de la toate specializările unei facultăți.

1. Testarea software

1.1. Definiție

Testarea  software este procesul căutării erorilor într-un program software, indiferent dacă acestea au cauze logice sau fizice. Obiectivul principal al testării software este găsirea erorilor, altfel spus, de a identifica neconcordanța dintre ceea ce este planificat să efectueze aplicația și ceea ce realizează în realitate. Testarea nu presupune identificarea cauzei erorilor și corecția acestora, acestea fiind activități specifice depanării.

Conform IEEE Standard Glossary (1983), definiia testării este:

"Procesul de exercitare sau evaluare a unui sistem prin mijloace manuale sau automate pentru a verifica dacă îndeplinește cerințele specificate sau pentru a identifica diferenele dintre rezultatele așteptateși cele reale."[6]

Testarea este privită ca o componentă majoră a calității software, dar este un proces scump și laborios, ce consumă de la o treime până la o jumătate din costul unui proiect.

Metodele moderne de elaborare a produselor software acordă o importanță deosebită efortului de înlăturare a erorilor de analiză, proiectare și programare. Acest lucru este realizat prin folosirea unor mijloace evoluate de testare. Activitile de testare ocup circa 30-50% din efortul total de dezvoltare, n funcie de natura aplicaiei.[1]

Un produs software testabil se consideră ca fiind inteligibil (structurat, concis și auto-descriptibil) și măsurabil (accesibil și cuantificabil).

Testarea nu este o doar fază, ci un întreg proces care trebuie integrat în toate fazele construcției produsului software, fiecare fază având modul său specific de testare. Acest lucru permite descoperirea erorilor devreme în procesul de dezvoltare software având drept consecință costuri mai mici de corecție.

Bill Hetzel, unul dintre fondatorii meseriei de testor considera (Complete Guide to Software Testing Processes) că: “Testarea este orice activitate având ca obiectiv evaluarea unui atribut ori a funcționalității unui program sau sistem și determinarea măsurii în care acesta realizează cerințele impuse.” [6]

1.2. Caracteristicile testării

Testarea nu permite tragerea unei concluzii definitive privind inexistența oricărei erori în sistemul testat. Aceasta nu trebuie confundată cu depanarea, scopul ei reprezentând creșterea calității sistemului testat prin eliminarea erorilor, reducerea timpului de dare în folosință, reducerea cheltuielilor legate de mentenanță, eliminarea insatisfacțiilor utilizatorilor.

Totodata testarea urmărește să pună în evidență situațiile în care sistemul nu funcționează corect, nu să demonstreze că sistemul este funcțional. Problema dificilă este aceea de a ști ce înseamnă că un sistem îndeplinește cerințele impuse. Pot să apară două concepții:

se iau în considerare numai cerințele impuse prin specificațiile de proiect

pe lângă specificațiile de proiect (dacă există) se iau în considerare și cerințele presupuse pe baza experienței celui ce testează precum și nivelul de satisfacție al utilizatorilor

Cu cât software-ul transformă mai repede defectele dintr-un program ȋn eșecuri, spunem că acesta are un nivel mai ridicat de testabilitate, ceea ce convine echipei de testare.

Pentru a obține produse cu un grad ȋnalt de testabilitate este necesară o colaborare strȋnsă ȋntre testori și dezvoltatori ȋncă de la ȋnceputul ciclului de viață al produsului.[2]

Nu există niciun proces de testare care să permită identificarea tuturor defectelor posibile ale unui produs software. Un proces de testare furnizează o viziune critică sau comparativă, studiind constrângerile și metricile care servesc drept criterii de acceptanță. Aceste criterii pot fi derivate din:

specificațiile tehnice

produsele asemănătoare comparabile

versiunile anterioare ale aceluiași produs

așteptările utilizatorului sau clientului față de produs

standardele relevante

legile în vigoare

Fiecare produs software are o audiență caracteristică. Testarea software este procesul care realizează evaluarea acceptabilității produsului din perspectiva utilizatorilor finali, audientei țintă și a cumpărătorilor într-un mod cât mai obiectiv.[3]

1.3. Nivelurile testării software

În dezvoltarea unui produs software testarea se realizează pe mai multe niveluri. Acestea sunt: testarea de module, testarea de integrare, testarea de sistem și testarea de acceptare (validare). În figura 1.3.1. este prezentat procesul de verificare și validare în cadrul ciclului de dezvoltare a unui produs software. Aici sunt identificate etapele de realizare a aplicației precum și etapele și nivelurile procesului de testare software.

Fig. 1.3.1. – Nivelurile testării software [4]

1.3.1. Testarea de module

Testarea de module presupune verificarea celor mai mici unități ale programului software care pot fi compilate independent. În programarea clasică modulul este considerat ca fiind un subprogram (funcție sau procedură).

Testarea de module pune accent pe verificarea interfețelor modulelor, structurilor de date locale, condițiilor de la limite, căilor de tratare a erorilor și căilor independente.

Deoarece modulele nu sunt programe de sine stătătoare, este necesar să se construiască programe sau funcții suplimentare care să ajute la testarea modulelor [4]:

programele conducătoare (drivers) care apelează modulele supuse testării cu datele de test construite și preiau rezultatele execuției.

module vide (stubs) care presupun ca funcțiile sau procedurile apelate de către modulul de testat să fie substituite cu subprograme care au același prototip, însă cu funcționalitate redusă la minim sau funcționalitatea dorită de cel care testează, care să simuleze efectul apelării modulelor reale

Acestea vor fi descrise detaliat în capitolele urmatoare.

1.3.2. Testarea de integrare

Testarea de integrare presupune gruparea componentelor programului și testarea interfeței dintre ele, construind astfel sistematic structura programului. Aceasta se poate realizeaza într-o manieră neincrementală sau incrementală.

Testarea neincrementală (big-bang testing) presupune integrarea componentelor prin gruparea tuturor modulelor dintr-o dată și testarea întregului ansamblu astfel obținut. Acest tip de integrare nu este recomandată, deoarece corectarea erorilor va fi foarte greu de realizat.[4]

Testarea incrementală constă în integrarea componentelor programului pas cu pas și testarea structurii obținute. Acest tip de testare permite alegerea secvenței în care modulele trebuie să fie testate. Astfel, această testare se poate realizeaza ascendent (bottom-up), descendent (top-down) sau mixt.

În cadrul metodei de testare ascendentă (bottom-up testing), testarea se realizează mai întâi la modulele de pe cel mai de jos nivel al ierarhiei programului, continuându-se apoi în sus cu testarea celorlalte module. Această metodă necesită construcția de programe conducătoare pentru a inițializa mediul și pentru a apela modulele. Astfel, programele care sunt de obicei critice de pe nivelul de sus sunt testate ultimele. În timpul acestui proces pot fi descoperite erori care pot influența multe module care au fost deja testate. După corecția tuturor acestor erorilor este necesar ca toate modulele de pe nivelurile de jos să fie testate regresiv.

În cadrul metodei de testare descendentă (top-down testing), modulul din vârful ierarhiei de programe este testat primul. Procesul de testare continuă apoi cu modulele de pe nivelurile inferioare. Această metodă necesită construcția de module vide asociate subprogramelor care nu sunt disponibile. Avantajul acestei metode constă în faptul că în cazul în care este descoperită o eroare în modulele de pe nivelurile înalte, acest lucru nu va avea impact asupra modulelor de pe nivelurile de jos care nu au fost încă implementate. Se poate evita astfel refacerea modulelor de pe nivelurile inferioare.[4]

În cadrul metodei mixte, se realizează întâi metoda descendentă, urmată apoi de metoda ascendentă. Această flexibilitate permite preluarea avantajelor ambelor metode. Metoda mixtă este cea mai potrivită modalitate de abordare în majoritatea aplicațiilor.

Pe măsură ce sunt adăugate noi module în cadrul testării de integrare, pot să intervină schimbări în cadrul programului software care să modifice comportamentul structurii obținute anterior. În acestă situație trebuie realizată și o testare de regresie. Prin acest proces se re-testează noua structură obținută, utilizând o parte din testele utilizate în etapa precedentă de integrare, pentru a se asigura ca nu s-a stricat nimic.[4]

1.3.3. Testarea de validare (acceptare)

Acest tip de testare are loc după ce toate erorile de interfață descoperite în timpul testării de integrare au fost corectate. Acesta se încheie cu succes atunci când funcționalitatea aplicației software este în conformitate cu cerințele specificate de beneficiar. Pentru testarea de validare se utilizează o serie de teste funcționale pentru a confirma faptul că aplicația software se comportă conform cerințelor.[4]

În cadrul acestui proces se regăsesc testările alfa și beta. Testarea alfa este realizată la firma care produce aplicația software, iar testarea beta este realizată la beneficiarii și utilizatorii finali ai aplicației. Aceștia primesc o versiune a aplicației apropiată de cea finală și o utilizează în scopul descoperirii erorilor și a problemelor de performanță și funcționalitate. Problemele apărute în cadrul acestei testări sunt raportate firmei care a realizat aplicația. După ce perioada acordată pentru testarea beta s-a terminat, toate erorile apărute sunt corectate, urmând să se realizeze versiunea finală a aplicației software.[4]

1.3.4. Testarea de sistem

După ce s-au realizat toate tipurile de testare menționate mai sus, se trece la testarea de sistem. Prin acest proces se testează întregul sistem în componența căruia intră produsul software testat anterior. Testarea de sistem presupune rularea unor teste specifice, astfel încât să poată fi examinate toate caracteristicile sistemului cum ar fi capacitatea de recuperare (recovery testing), securitatea (security testing), rezistența la solicitare (stress testing), rezistența la încărcare (load testing) și performanța (performance testing), etc.[4] Acestea vor fi detaliate ȋn capitolele următoare.

1.4. Principiile testării

Principiile testării software sunt:

Toate testele trebuie să fie legate de cerințele (explicite și implicite) impuse produsului. Acest principiu ne arată ca ȋn primul rând este necesar să fie puse ȋn evidență și eliminate acele defecte care ȋmpiedică produsul să satisfacă cerințele utilizatorilor. Dacă ȋn urma testelor efectuate sunt puse ȋn evidență și alte defecte/anomalii, se va analiza cu atenție ȋn ce măsură ele pot fi acceptate, cel puțin momentan.

Testele trebuie săfie planificate cu mult ȋnainte de efectuarea lor. Planificarea testelor pentru o componentă a produsului poate să ȋnceapă imediat după ȋncheierea formulării specificațiilor pentru acea componentă. Această abordare corespunde modelelor V și W de dezvoltare a unui proiect și este necesară deoarece pregătirea testelor este ȋn general laborioasă, implicând scrierea unui cod special pentru testare și eventual chiar crearea unor platforme hardware adecvate.

Principiul lui Pareto. Formularea adaptată a acestui principiu ȋn programare este: “80% dintre defectele descoperite sunt concentrate ȋn 20% din componentele testate”. Un corolar al acestui principiu ar putea fi formulat ȋn felul următor: “probabilitatea descoperirii de noi defecte este mai mare ȋn modulele ȋn care au fost deja descoperite defecte”.[3]

Testarea ȋncepe de la “simplu” și evoluează către “complex”. Acest principiu ne arată că primele teste planificate și executate se referă la componente de complexitate cât mai mică (uneori doar câteva linii de cod care realizează o funcție bine precizată) pentru a permite localizarea cât mai rapidă a defectelor. Numai după ce defectele de la acest nivel au fost eliminate, se trece la testarea unor grupe de module și ȋn final la testarea ȋntregului produs.

Atunci când definim un test, este esențial să precizăm la ce rezultate trebuie să ne așteptăm.

Testarea exhaustivă nu este posibilă, adică niciodată nu putem garanta că dintr-un produs au fost eliminate toate defectele. Acest lucru se datorează faptului că activitatea de testare este o activitate economică cu resurse limitate și care trebuie să se desfășoare ȋntr-un interval de timp acceptabil pentru toți partenerii la proiect iar numărul total de teste necesare pentru a acoperi toate situațiile posibile poate fi foarte mare chiar ȋn cazul unor componente relativ simple.

Se vor interpreta cu grijă rezultatele tuturor testelor.

Trebuie să testăm cu aceași atenție atât situațiile normale de funcționare cât și pe cele anormale sau chiar inacceptabile.

Nu este suficient să punem în evidență că un produs nu realizează ceea ce se presupune că trebuie să realizeze. Este necesar să verificăm și dacă nu cumva realizează ceea ce nu trebuie să realizeze.

Nu se vor distruge datele și/sau echipamentele de testare utilizate, până când nu se renunță la produsul testat.

Nu se evalueaza efortul de testare bazându-se pe ipoteza că nu vor apare noi eșecuri.

Pentru a fi cu adevarat eficiente, testele trebuie realizate de o altă echipă decât cea care a dezvoltat produsele testate deoarece ȋn timp ce dezvoltatorul este orientat pe reducerea timpului de dare ȋn folosință, testorul este orientat pe asigurarea calității produsului.

Testarea este o activitate creativă de un înalt nivel intelectual.[3]

2. Tipuri de teste și metode de testare

2.1. Clasificarea tipurilor de testare

După modul în care se realizează testarea se pot distinge 2 categorii de testare:

testare automată – presupune creare de teste și scripturi care vor fi rulate automat pentru a verifica modul în care funcționează aplicația

testare manuală – presupune verificarea modului în care funcționează aplicația de către un testor

O altă clasificare se poate face după ceea ce implică procesul de testare, astfel aceasta poate fi de 2 feluri:

testare statică – are în vedere analiza codului sursă a programului fără rularea acestuia, independent de datele de intrare.

testare dinamică – presupune rularea aplicațiilor software pentru a genera date de test și execuția acestora cu seturile de date de test obținute.

Din punctul de vedere al strategiei de testare aceasta poate fi:

testare structurală (white-box) – este o strategie de testare care necesită accesul la codul sursă și la structura programului și pune accentul pe acoperirea prin teste a căilor, ramificațiilor și fluxurilor programului. Principalele metode de testare structurală au în vedere gradul în care cazurile de test acoperă sau execută codul sursă al programului.

testare funcțională (black-box) – nu necesită cunoașterea structurii interne a programului, cunoștințe despre program, în schimb necesită cunoașterea a cum ar trebui să fie comportamentul extern al programului, bazându-se pe specificațiile acestuia.

testare mixtă (gray-box) – implică o cunoștință a structurilor de date interne și a algoritmilor în scopul elaborării testelor, ce vor fi executate la nivel de teste black-box. Cel care testează nu trebuie neapărat să aibă acces la codul sursă pentru a realiza un astfel de test.[12]

Un alt criteriu de clasificare poate fi modul în care procesul de testare influențează procesul de dezvoltare al unei aplicații software, astfel se disting mai multe tehnici:

Behavior-driven development (BDD) – după implementarea funcționalităților aplicației se scriu teste care să verifice corectitudinea codului scris și comportamentul acestuia în situații extreme cu parametrii limită

Test-driven development (TDD) – presupune crearea testelor înaintea implementării. Inițial se crează un test simplu care eșuează. Apoi se trece la implementarea funcționalității necesare astfel încât să treacă testul. Se refactorizează codul și treptat testul se extinde astfel încât să acopere tot mai multe funcționalități. Urmează apoi implementarea treptată a acestor funcționalități astfel încât să treacă testul.[ 11]

Folosind o astfel de abordare codul final va arăta foarte diferit în comparație cu cazul în care s-ar fi pornit de la implementarea funcționalitățiilor, dar această metodă dă posibilitatea definirii foarte clare a comportamentului codului scris și al așteptărilor de la acesta.

S-a observat că în practică tehnica TDD nu este o metodă foarte eficientă și are multe lacune, nereușind să acopere toate cerințele procesului de dezvoltare al aplicațiilor actuale.[10] Principiul TDD este ilustrat în figura 2.1.1.

Fig. 2.1.1. – Principiul de funcționare al TDD

2.2. Tipuri de teste

În funcție de ceea ce se testează, se disting mai multe categorii de teste:

teste de bază – se asigură că sistemul poate fi instalat, configurat și adus într-o stare funcțională.

teste funcționale – verifică că cerințele precizate în documentul de specificații ale sistemului sunt îndeplinite

teste nefuncționale – verifică atributele componentelor sau ale sistemului, nu se leagă de funcționalitate

2.2.1. Teste funcționale

Testele funcționale se pot clasifica în:

Teste de siguranța (security tests) – investighează funcții (ex. Firewall) care au în vedere detecția de amenințări cum ar fi viruși și factori dăunători și modul în care sistemul este protejat împotriva accesului neautorizat

Teste de interoperabilitate (interoperability tests) – combină diferite elemente ale sistemului într-un singur mediu de testare, pentru a asigura funcționarea lor corectă împreună. Sunt create pentru a asigura că sistemul poate fi interconectat cu alte sisteme și va continua să funcționeze corect. Acestea sunt de două tipuri: de compatibilitate (compatibility tests – verifică funcționarea versiunii actuale a sistemului în cadrul unei platforme mai vechi) și de compatibilitate inversă (backward compatibility – verifică menținerea vechilor funcționalități)

Teste de fum (smoke tests) – scopul acestora este să pună în evidență cu un minim de efort dacă un produs este funcțional înainte de a trece la realizarea unor teste detaliate. Testele din această categorie sunt teste ușoare, cu timp de execuție mic și sunt focalizate pe modificările introduse. Trecerea acestui test nu garantează calitatea impusă produsului, deci nu elimină celelalte categorii de teste.

Teste de integrare (integration tests) – implică testarea combinată a diferitelor părți dintr-o aplicație pentru a vedea dacă funcționează corect. Aceste "părți" pot fi module de cod, aplicații individuale, aplicații client-server într-o rețea etc.

Teste pentru unități (unit tests) – verifică funcțiile sau module de cod. De obicei sunt făcute de programatori deoarece presupun cunoștințe avansate a design-ului intern al aplicației și codului. Nu întotdeauna sunt ușor de executat dacă aplicația nu are o arhitectură bine pusă la punct. Executarea lor poate presupune dezvoltarea de module driver sau de module vide.

Teste de sistem (system tests) – ajută la realizarea unei testări de tip black-box bazată pe specificații care acoperă toate părțile sistemului.

Teste de acceptare (user acceptance tests) – sunt realizate la sfârșitul implementării unor funcționalități sau al întregii aplicații care determină dacă software-ul este satisfăcător pentru un end-user sau client. Testarea de acceptare este de 2 feluri:

testare alfa – se efectuează folosindu-se specificația cerințelor utilizator ului

testare beta – programul este distribuit unor utilizatori selecționați, realizându-se astfel testarea lui în condiții reale de utilizare.

Teste de instalare/dezinstalare(install/uninstall tests) – presupun testarea parțială sau integrală a procesului de instalare sau upgrade.

Teste de la un capăt la altul (end-to-end tests) – sunt similare cu testele de sistem. Aceste teste implică o testare de nivel 'macro'. Presupune testarea aplicației și a tuturor funcționalităților acesteia în mediul în care va fi folosită.

Teste negative (negative tests) – solicită aplicația, producând deliberat cazuri complicate, neobișnuite sau particulare pentru a forța apariția erorilor

2.2.2. Teste nefuncționale

Testele nefuncționale se clasifică în:

Teste de utilizabilitate (utilizability tests) – determină masura în care produsul software este ușor de înțeles, ușor de învățat, ușor de operat și atractiv (user-friendly) pentru utilizatorii supuși unor condiții specifice.

Teste de performanță (performance tests) – măsoară performanțele reale ale sistemului, comparate cu cele teoretice. Metrica performanțelor ce trebuie măsurate variază de la aplicație la aplicație. Dacă măsuratorile de performanță sunt nemulțumitoare, atunci se iau măsuri pentru îmbunătățire (rescrierea codului, alocarea mai multor resurse, redesign de sistem). Performanța poate fi măsurată, urmărind:

timpul de răspuns €“

ieșirile sistemului €“

utilizarea resurselor

Teste de compatibilitate (compatibility tests) – presupun testarea modului în care funcționează software-ul pe anumite configurații hardware, sisteme de operare sau rețele.

Teste de scalabilitate (scalability tests) – verifică sistemul pentru a își atinge limitele sale tehnologice. Un sistem poate funcționa într-un scenariu cu utilizare limitată, dar nu poate fi extins uneori. Timpul de rulare al unui sistem poate crește exponențial, în funcție de cerințe și poate ceda după o anumită limită. O aplicație este scalabilă dacă o creștere a încărcării sistemului necesită doar resurse adiționale, fără modificări extensive ale aplicației. Limitele tehnologice sunt de obicei:

limitări de stocare a datelor

limitări de bandwidth

limitări de viteză – CPU

Teste de stres (stress tests) – presupun evaluarea și găsirea comportamentului unei componente software, la limită sau în afara limitelor sale specificate tehnic. Sistemul este în mod intenționat stresat, prin împingerea lui dincolo de limitele specificate. Testele includ asigurarea de resurse puține și testarea pentru incompatibilități. Testele de stress se asigură că sistemul se comportă acceptabil în cele mai rele condiții. Dacă limitele sunt depășite și sistemul cedează, ar trebui ca un mecanism de revenire să pornească automat. În testele de stres, trebuie urmărită "stricarea" aplicației și expunerea defectelor ce pot apărea în condiții de stres.

Teste de încărcare și stabilitate (load tests) – presupun asigurarea stabilității sistemului pe o perioadă lungă de timp cu încărcare completă (load). Un sistem poate funcționa foarte bine când este testat de câțiva ingineri, care îl folosesc în mod corect. Totuși, când intervin un număr mai mare de utilizatori, care nu cunosc sistemul, și aplicații care rulează luni fără repornire, se pot întâlni diverse probleme cum ar fi:

sistemul încetinește

apar probleme de funcționare

sistemul se oprește treptat

sistemul cedează complet

Acest tip de teste ne ajută să înțelegem cum se va comporta sistemul în viața reală iar pentru acest lucru trebuie testate scenarii cât mai realiste.

Teste de fiabilitate (reliability tests) – presupun măsurarea capacității sistemului de a rămâne operațional pentru perioade lungi de timp. Fiabilitatea sistemului se exprimă de obicei în termeni de timp mediu până la cedare (MTTF – mean time to failure). Pe măsură ce se testează sistemul, se observă erorile,se încercă îndepărtarea defectele și continuarea testării. Pe măsură ce avansează testarea, se înregistrează duratele de timp între eșecuri succesive.

Teste de regresie (regression tests) – nu sunt teste noi ci se selectează teste dintre cele existente și sunt executate pentru a asigura că nu este nimic defect în noua versiune a produsului software. Principala idee a testării pentru regresie este verificarea faptului că nici un defect nu a fost introdus în porțiunea nemodificată a sistemului, datorită schimbărilor aduse în alte părți ale sistemului. În timpul testării sistemului, multe defecte sunt descoperite și codul este modificat pentru a repara aceste defecte. Testele de regresie se efectuează când produsul sau mediul său au fost schimbate: Se pot executa la orice nivel de testare si pot fi automatizate (din motive de costuri și de program)

Teste de revenire (recovery tests, failover tests) – testează modul în care un sistem iși revine după defectarea întregului sistem

Teste de documentatie (documentation tests) – verifică acuratețea tehnică și lizibilitatea manualelor de utilizare, inclusiv a tutorialelor și a paginilor de on-line help.

3. Testarea automată

3.1. Testare automată vs. testare manuală

Când vine vorba de testare, cea mai des întâlnită problemă într-o companie este dacă să se automatizeze procesul de testare sau să se testeze manual. Nu toate testele pot fi automatizate și de cele mai multe ori poate fi dificil de decis ce să se automatizeze și ce să se testeze manual. Testarea manuală și testarea automată sunt mai degrabă două procese diferite, decât două căi diferite de a executa același proces. Dinamica lor este diferită precum și modul de a releva bug-urile.

Testarea manuală este mai folositoare în situațiile în care este nevoie urgent de rezultatele unor tipuri de teste specifice și limitate, când se dorește ca timpul de feedback să fie foarte scurt, iar costurile să fie relativ mici. Cum îmbunătățirea calității produsului implică costuri adiționale pentru găsirea bugurilor și gestionarea acestora până la repararea lor definitivă, testarea manuală s-a dovedit a fi în timp extrem de costisitoare. Testarea manuală pe scară largă presupune alocarea de resurse hardware și umane destul de mari, iar riscul să apară erori este amplificat de factorul uman.

Testarea automată necesită un efort inițial mai mare pentru planificarea, organizarea și producerea testului, criteriul principal în obținerea de rezultate bune fiind planificarea atentă, amănunțită și precisă a acestuia.[13]

Avantajele testării automate se pot clasifica în:

a) avantaje privind eficiența și costurile

prevenirea erorilor prin abordarea structurată a procesului de dezvoltare a proiectului

detecția erorilor care au ajuns până în faza de producție (prin teste de regresie automată)

reutilizarea informației acumulate (condiții de test, scripturi)

reducerea creării de noi scripturi (refolosindu-le și adaptându-le pe cele vechi)

execuția automată a testelor de performanță în fazele de început ale proiectului poate evita eforturile de redesign în fazele ulterioare

odată ce scripturile de testare automată sunt implementate, o parte din personal poate fi redirecționat către alte necesități

costurile pe termen lung sunt reduse

b) avantaje privind economia de timp

analiză rapidă și exactă în cazul schimbării parametrilor sistemului

durată scurtă a ciclurilor de testare

estimări mai exacte pentru procesul de planificare a testului

posibilitatea efectuării mai multor teste (scripturile de testare pot fi rulate și după orele de program economisind astfel timp)

generarea rapidă a condițiilor de testare

găsirea rapidă a problemelor

repetarea testelor nu necesită eforturi mari

reducerea volumului de testare manuală care poate dura mai mult ca cea automată

posibilitatea rulării testelor pe mai multe mașini scăzând astfel timpul de testare

c) avantaje privind calitatea

o mai bună înțelegere a scopului testării

o acoperire mai mare a elementelor de testat

acoperirea tuturor etapelor de testare de la concepție până la lansare

permite vizualizarea în orice moment a proporției în care este acoperit de teste codul testat (code coverage) pentru a ști cât de sigur este acel cod împotriva erorilor

rezultate mai consistente datorită repetabilității testelor

posibilitatea de a testa continuu/ciclic

posibilitatea simulării testării cu mai mulți utilizatori

permite executarea de teste de compatibilitate a programelor pe mai multe configurații

permite automatizarea secvențelor lungi de teste și a proceselor care necesită operațiuni complexe

permite compararea automată a rezultatelor

procesul de scriere a codului devine mult mai flexibil

permite rularea mai multor teste de regresie pe un cod care se schimbă des

Avantajele testării manuale sunt:

rezolvarea problemelor de interfață: scrierea corectă a textelor, mesajelor, aranjarea corectă în pagină, în ordinea care trebuie, vizibilitatea elementelor etc.

realizarea scenariilor de test poate fi o treabă de durată și anevoioasă și implică o cunoaștere temeinică a întregului sistem

dacă scenariile de test trebuiesc rulate de un număr mic de ori e mult mai probabil să se prefere testarea manuală

permite testorului să facă mai multe teste ad-hoc

costurile pe termen scurt sunt reduse

cu cât un testor petrece mai mult timp verificând un modul, cu atât cresc șansele de a găsi mai multe defecte și posibile greșeli de utilizare

Dezavantajele testării automate sunt:

e mult mai scump să automatizezi, investițiile inițiale sunt mai mari decât în cazul testării manuale

nu se poate automatiza totul, anumite teste trebuiesc făcute manual

crearea scripturilor necesită un efort substanțial (nu întotdeauna justificat)

scripturile testelor trebuie întreținute

testele execută secvențe de acțiuni programate, nu posedă nici un fel de inteligență spre deosebire de testarea manuală unde testorul poate lua anumite decizii

Dezavantajele testării manuale sunt:

testele manuale pot fi mari consumatoare de timp

pentru fiecare versiune lansată a aplicației trebuiesc rulate aceleași seturi de teste ceea ce poate deveni monoton

fiind implicat un operator uman, acestea sunt predispuse la inconsecvențe de la o testare la alta

Sunt multe lucruri pe care uneltele de testare automată nu le pot face și este foarte important ca aceste limitări să fie cunoascute încă de la început pentru putea a alege unealta cea mai potrivită. Un sistem de testare automată nu poate spune când ceva "arată bine" pe ecran sau când o poză sau fereastră nu este bine încadrată. De asemenea un test automat nu poate decide dacă logica programului are lipsuri funcționale, acesta putând verifica doar măsura în care au fost definite cerințele aplicației respective. Unele teste, mai ales cele pentru aplicații mici și pentru aplicații care se concentrează mai ales pe grafică și nu pe business logic, sunt mult mai ușor realizabile de către operatorul uman decât de către un calculator. De aceea trebuie alcătuit un plan bine definit al procedurii de testare, când, unde și în ce condiții este fiabilă introducerea automatizării.[13]

O temere întâlnită adesea este că testorii își vor pierde locul de muncă o dată cu introducerea testării automate. În realitate, testorii devin mult mai importanți pentru că acum doar ei pot descoperi problemele ascunse, greu sau imposibil de găsit prin teste automate. Ei ajută la creșterea probabilității că totul funcționează corect de la 80+% la aproape 100%.[29] Acest compromis între cele 2 tipuri de testare este așa-numita "testare parțială". Această soluție este între combinație testare manuală și testare automată, aceasta din urmă fiind folosită numai acolo unde se pot obține beneficii maxime.[18]

3.2. Testarea automată i componentele acesteia

Testarea automat const în activitatea de concepie a cazurilor de test, de execuie a testelor i de evaluare a rezultatelor testelor, n diferite etape ale ciclului de via al programelor și presupune utilizarea a unui program pentru executarea procedurilor sau a întregilor scenarii de testare.

Cea mai des întâlnită abordare este testarea unitară (unit testing). Aceasta este o metodă de testare software, prin care unitățile individuale de cod sursă sau seturi de unul sau mai multe module de program împreună cu datele de control ale acestora sunt testate pentru a determina dacă acestea sunt potrivite pentru utilizare.

Un test unitar (unit test) este o instanță a unui caz concret de utilizare (use case) compusă din date intrare, condiții de execuție și rezultate așteptate. Testul unitar const n execuia programului pentru un set de date de intrare convenabil ales, pentru a verifica dac rezultatul obinut este corect.[21]

Structura unui test unitar este ilustrată în figura 3.2.1. Potrivit acestei scheme testul este alcătuit din unul sau mai multe cazuri de test (test case) care sunt grupate într-o suită (test suite).

Un caz de test este o entitate care conține minim următoarele informații:

un set de date de test (a set of test input) – date primite de codul testat de la o sursă externă (umană, software, hardware);

condiții de execuție (execution conditions) – condițiile impuse pentru executarea unui test (o stare particulară a bazei de date, setările sistemului de operare sau ale altor programe auxiliare, configurarea unui dispozitiv hardware etc);

ieșirile estimate (expected outputs) – rezultatele așteptate ca urmare a execuției codului cu datele de test și ȋn condițiile specificate.

Fig. 3.2.1. – Structura unui test unitar

Cazurile de test se aleg astfel nct s fie puse n eviden, dac este posibil, situaiile de funcionare necorespunztoare. Profesionalismul în testare constă în abilitatea de a selecta numărul minim de cazuri de testare eficientă ce va fi capabil să verifice numărul maxim de funcții ale sistemului.[20]

Fiecare caz de test este înglobat într-un context de test (test fixture). Acesta este un set de condiții prealabile necesare pentru a rula un test și presupune rularea a două metode speciale numite setUp și tearDown. Metoda setUp este apelată înainte de rularea testului pentru a construi contextul (condițiile și starea aplicației) în care va fi rulat acel test. La finalul execuției cazului de test se apelează metoda tearDown care are rolul de a șterge contextul testului precedent pentru a nu influența rularea următorului caz de test. Toate cazurile de test din cadrul unei suite au același context de test.

Pentru a se verifica dacă rezultatul obținut e același cu cel așteptat se folosesc afirmațiile (asserts). O afirmați eeste un predicat (o declarație adevărată sau falsă) plasat într-un program cu care se indică faptul că dezvoltatorul testului crede că predicatul este întotdeauna adevărat în acel loc. Dacă o afirmațiese evaluează la fals în timpul rulării unui test, acel test va eșua și execuția testului va fi oprită.

Întreaga suită de cazuri de test este rulată de un program executabil (test runner) care returnează rezultatele testelor în diferite formate. Aceste rezultate pot fi interpretate cu unelte specifice.

Testarea ar trebui s fie un proces exhaustiv care s asigure exersarea tuturor cilor posibile din program, dar o astfel de testare este imposibil. Din această cauză cazurile de test trebuie create în așa fel încât să acopere cât mai multe cazuri ce pot apărea condiții reale de utilizare a aplicației testate. Astfel trebuie testat modul de funcționare al programului atât la intrri valide cât i la intrri nevalide.

Se pot distinge dou metode de generare a cazurilor de test care de cele mai multe ori sunt folosite împreună pentru o testare optimă.

metoda black-box (testare funcională) – cazurile de test sunt determinate pe baza specificaiei componentei testate, fr cunoaterea modului în care e realizată

metoda white-box (testare structurală) – cazurile de test sunt determinate prin analiza codului componentei testate

Specificațiile cazului de test sunt niște documente pe baza cărora se proiectează cazul de test. Acestea documentează ce anume trebuie testat. Este la latitudinea fiecare organizații să decidă conținutul și formatul documentelor pentru precum și sistemele pe care le vor păstra. Fiecare organizație poate decide introducerea în cazul de test a unor informații adiționale pentru a-i crește valoarea ca obiect reutilizabil sau pentru a oferi informații detaliate testorilor și dezvoltatorilor. Pentru o bună organizare se folosesc sisteme care permit stocarea și organizarea acestor documente. Acestea permit accesul tuturor celor implicați în procesul de testare și redau stadiul în care se află procesul de testare în orice moment.[2]

Testarea unui modul (o funcie, o clas, etc.) este realizat de programatorul care implementeaz modulul. Toate celelalte teste sunt efectuate, n general, de persoane care nu au participat la dezvoltarea programului.

Scopul testării unui modul este de a se stabili că modulul este o implementare corectă a specificației sale. În cursul testării unui modul, acesta este tratat ca o entitate independent, care nu necesit prezena altor componente ale programului. Testarea izolat a unui modul ridic dou probleme:

simularea modulelor apelate de cel testat

simularea modulelor apelante

Modulele prin care se simuleaz modulele apelate de modulul testat se numesc module vide (stub) .Un modul vid are aceeai interfa cu modulul testat i realizeaz n mod simplificat funcia sa returnând doar ceea ce ii este necesar metodei testate.

Cazurile de apel ale modulului testat de ctre celelalte module ale programului sunt simulate n cadrul unui modul driver. Modulul driver apeleaz modulul testat furnizându-i ca date de intrare, datele de test ale modulului. Datele de test pot fi generate de modulul driver, preluate dintr-un fiier sau furnizate de testor ntr-o manier interactiv.[19] Interacțiunea dintre aceste elemente este ilustrată în figura 3.2.2.

Fig. 3.2.2. – Structura programului executabil pentru testarea izolată a unui modul [19]

3.3. Etapele testării automate

Un sistem de testare automată trebuie să aibă la bază două caracteristici principale:

module reutilizabile

întreținerea și urmărirea activității dintr-un singur punct de control

Datorită acestui fapt, una din calitățile care trebuie să le aibă un astfel de sistem este capabilitatea de a fi ușor configurat și adaptat în același ritm cu software-ul ce se testează .

Sistemele de testare automată sunt o tehnologie în plină dezvoltare care au ca scop descoperirea și raportarea eventualelor defecte, mărirea longevității produsului și reducerea procesului de întreținere.

Testarea automată înseamnă mai mult decât o simplă captură de ecran și răspunsul la câteva scripturi, ea trebuie să înceapă cu planificarea și design-ul procedurii de testare, să conțină o serie de teste repetabile, o interfață de management al scenariilor de test și un mecanism de raportare și gestionare a bug-urilor descoperite în urma testării. Un sistem de test evoluat sprijină utilizatorii printr-un sistem de documentare pe tot parcursul acestui proces.[13]

Într-o abordare mai detaliată testarea automată înseamnă: planificare, design, execuție și management.

În etapa de planificare se identifică cerințele și funcționalitățile care trebuie testate. Acestea se grupează în condiții de test pentru care sunt create cazuri de test. În această etapă se

crează mai multe documente specifice:

Software Test Plan (STP) care detaliază: scopul testării, planificarea în timp, cerințele și funcționalitățile ce se testează.

Test Requirement Definition (TRD) care specifică ce cazuri trebuie testate pentru fiecare cerință

Software Test Description (STD) care specifică pas cu pas ce se execută și ce rezultat se așteaptă pentru fiecare caz de test

Etapa de design presupune construcția scripturilor de test și generarea testelor de rulare. Aceasta este urmată de etapa de execuție care presupune:

crearea scenariului de rulare a scripturilor

rularea uneltelor monitor pentru înregistrarea datelor

înregistrarea rezultatelor pentru fiecare rulare

raportarea și gestionarea bug-urilor

În ultima etapă, cea de management, se generează un raport Software Test Report (STR) care sumarizează rezultatele ciclurilor de testare și conține concluzii despre calitatea sistemului testat. Acesta este deobicei generat de unealta cu care se ruleaza testele.

3.4. Tehnologii de testare automată

În ultimul timp pentru testarea automatizată se folosesc tot mai des asa-numitele xUnit frameworks. Ele permit testarea codului de program pentru a verifica programul în circumstanțe diferite. De exemplu, aceleași proceduri de testare se folosesc pentru a testa comportamentul programului în diferite diferite sisteme de operare sisteme de operare.

Din această familie de framework-uri, am folosit JUnit pentru testarea codului Java și QUnit pentru testarea codului JavaScript. Modul acestora de funcționare și configurare va fi detaliat în capitolele următoare.

Aceste unelte sunt limitate doar la testarea codului, nefiind capabile să determine dacă interfața grafică cu utilizatorul funcționează corect sau este afișată în mod corespunzător. De aceea în completarea acestora vin framework-uri precum JMeter sau Selenium. Acestea permit înregistrarea sau crearea de teste care să simuleze interacțiunea utilizatorului cu aplicația supusă testării.

Toate testele automate pot fi integrate în unelte specifice pentru a fi rulate automat fără intervenția operatorului uman. Un exemplu de unealtă este Jenkins. Acesta permite definirea unor "job-uri" pentru rularea automată a testelor în diferite condiții. De exemplu, testele ar putea fi programate să ruleze în fiecare seară după terminarea orelor de program pentru a se verifica dacă modificările din timpul zilei au afectat funcționalitățile aplicației. De asemenea s-ar putea configura rularea acestora după fiecare publicare a codului pe sisteme de control al reviziilor. Astfel se realizează procesul de integrare continuă (Continous Integration). Acesta are scopul de a omogeniza contribuția tuturor programatorilor la aplicația implementată asigurându-se că nu apar probleme de integrare a diferitelor funcționalități.

4. Aplicația "Catalog facultate"

Aplicația utilizată ca și studiu de caz pentru ilustrarea managementului procesului de testare implementează un catalog online al unei universități.

Scopul acestei aplicații este de să ajute atât studenții cât și cadrele didactice să gestioneze sau să vizualizeze notele într-un mod cât mai eficient. Totodată, această aplicație oferă o evidență clară a tuturor departamentelor și specializărilor facultății precum și a tuturor studenților înscriși la acestea.

Cu ajutorul acestei aplicații se pot gestiona foarte ușor studenții, notele acestora, specializările, profesorii, materiile și se poate avea în orice clipă o evidență clară a acestora.

Aplicația este destinată mai multor tipuri de utilizatori:

utilizatori cu drepturi de vizualizare (studenți, părinți, profesori, secretari)

utilizatori cu drepturi de administrare (profesori, secretari)

Aplicația este alcătuită din 2 module:

Catalog studenți – secțiune disponibilă tuturor tipurilor de utilizatori

Administrare catalog – secțiune disponibilă doar celor cu drepturi de administrare

În funcție de drepturile fiecărui utilizator acesta va avea disponibile în ecranul de start modulele aplicației ilustrate în figura 4.1.

Fig. 4.1. – Modulele aplicației

Secțiunea "Catalog studenți" (prezentată în figura 4.2.) oferă utilizatorului posibilitatea să vizualizeze toate notele studenților. Acest lucru este posibil alegând:

Departamente ale facultății

Specializări ale unui departament

Ani de studii ai specializării

Studenți din anii de studii aleși

Fig 4.2. – Secțiunea"Catalog studenți"

Secțiunea "Administrare catalog" (prezentată în figura 4.3.) oferă posibilitatea înregistrării unui student nou precum și posibilitatea adăugării sau modificării notelor tuturor studenților. De asemenea această secțiunea oferă posibilitatea înregistrării noilor profesori, adăugării de noi specializări pentru fiecare departament precum și posibilitatea adăugării de noi materii pentru fiecare specializare.

Fig 4.3. – Secțiunea "Administrare catalog"

Fiind o aplicație web, aceasta este constituită din componenta de server (server-side) și componenta de client (client-side).

4.1. Dezvoltare server-side

Pentru dezvoltarea componentei de server am utilizat limbajul Java, framework-ul Java Servlets și unealta MSSQL Server 2012, iar pentru componenta de client am utilizat framework-ul SAP Fiori. Toate aceste unelte și tehnologii, împreună cu modul încare au fost folosite, vor fi detaliate în capitolele ce urmează.

4.1.1. Java

Java este o tehnologie inovatoare lansată inițial de Sun Microsystems și achiziționată ulterio rde Oracle. Este formată dintr-un limbaj de programare de nivel înalt pe bază căruia sunt construite o serie de platforme destinate implementării de aplicații pentru toate segmentele industriei software.

Acesta este un limbaj orientat pe obiecte dar nu este pur obiectual din cauză că deține și

tipuri primitive de date. Caracteristicile principale ale acestui limbaj sunt:

simplitatea

ușurința

robustețea

este complet orientat pe obiecte eliminând astfel stilul de programare procedural

neutralitatea arhitecturala, neținând cont de arhitectura fizică a mașinii pe care rulează

portabilitatea este data de codul compilat si interpretat care este independent de platforma pe care rulează

performanța

Limbajul de programare Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvări unor probleme din cele mai diverse domenii. Aceste tehnologii au fost grupate în așa numitele platforme de lucru, ce reprezintă seturi de librării scrise în limbajul Java precum și diverse programe utilitare folosite pentru dezvoltarea de aplicații sau componente destinate unei anumite categorii de utilizatori. Exemple de platforme sunt: J2SE (Standard Edition), J2ME (MicroEdition), J2EE (Enterprise Edition).

Toate aplicațiile Java sunt transformate în octeți (fișiere *.class) și rulate de către JVM (JavaVirtual Machine).Acest lucru îi dă portabilitate, codul compilat putând fi executat pe oricare mașină virtuală.

La realizarea acestei aplicații am folosit platforma de lucru J2EE și versiunea de limbaj

Java7. Această platformă de lucru vine în completarea J2SE și este destinată creării de aplicații

de tip enterprise. Aceste aplicații au arhitecturi complexe și sunt împărțite pe mai multe nivele.

J2EE face legătura dintre aceste nivele, mapează relațional obiectele și pune la dispoziție web

service-uri și suport pentru rețele.[16]

Pentru această aplicație am utilizat limbajul Java pentru a implementa nivelul DAO al aplicației precum și nivelul Business Service.

Nivelul DAO conține logica de extragere a datelor din baza de date precum și logica de inserare sau modificare a acestora.

Nivelul Business Service conține logica de procesare a datelor extrase și de convertire a acestora în format json pentru a putea fi trimise interfeței grafice cu utilizatorul.

4.1.2. Java Servlet

Un servlet este o clasă scrisă în limbajul Java al cărei scop este generarea dinamică de date într-un server HTTP. O astfel de clasă poate crea atât conținut HTML, cât și documente XML,imagini, alte fișiere etc. În cea mai mare parte servlet-urile sunt folosite împreună cu protocolul HTTP, deși există posibilitatea de a utiliza servlet-uri generice care nu sunt legate de un anumit protocol. Așadar prin „servlet” se înțelege de obicei „servlet HTTP”.

Servlet-ul este o funcționalitate din platforma J2EE care extinde capacitățile unui server. Un servlet nu poate fi executat direct de către server, ci de către un container web. Acesta răspunde la diferite tipuri de cereri (requests) venite de la paginile publicate pe un server. Pentru a răspunde unei cereri de la un client (de obicei un browser) către un anumit servlet, serverul trimite mai departe cererea către container, care se ocupă de instanțierea obiectului respectiv și de apelarea metodelor necesare. Exemplele de containere web care suportă servlet-urile includ Apache Tomcat (acest apoate fi rulat și ca server de sine stătător, dar performanțele sale nu se compară cu cele ale unui server web dedicat precum Apache). [17]

Servlet-urile sunt folosite de obicei pentru a procesa datele primite de la un form HTML, de a furniza dinamic datele extrase dintr-o bază de date sau de a realiza diferite operații în afara

paginii web. Acestea pot fi apelate folosind URL-ul lor direct în browser sau în cadrul altor

pagini web.

La aplicația prezentată în această lucrare am folosit tehnologia Servlet 2.5 pentru a transmite interfeței grafice datele care trebuie afișate în format json precum și pentru primirea datelor ce trebuie salvate în baza de date.

4.1.3. MSSQL Server 2012

Microsoft SQL Server este un sistem de gestionare de baze de date relaționale (RDBMS –

Relational Database Management System) produs de compania americană Microsoft Corp.

Limbajele primare de interogare sunt MS-SQL și T-SQL. Este un sistem destinat bazelor de date

de dimensiuni foarte mari.

Datele afișate în interfața grafică a aplicației prezentate sunt persistate într-o bază de date de tip MS SQL. Pentru a extrage datele necesare sau pentru a insera noi date am folosit o conexiune de tip JDBC (Java Database Connectivity).

JDBC este o tehnologie dezvoltată de Oracle care definește modul în care un client are acces la server-ul de baze de date. Acesta pune la dispoziție metode de interogare a bazei de date și de modificare a datelor din aceasta. Este conceput pentru baze de date relaționale. Am folosit acest tip de conexiune pentru a selecta informațiile necesare din baza de date folosind limbajul Java. Pentru a realiza acest lucru am folosit un driver JDBC (MSSQLJDBC-1.2.jar).

4.2. Dezvoltarea client-side

4.2.1. SAPUI 5 – SAP Fiori

SAPUI 5 este un framework JavaScript ce constituie o platformă de dezvoltare a

aplicaților web de business moderne . Acest framework conține o bibliotecă JavaScript de controale suportate de toate browser-ele, destinate aplicaților web de tip RIA (Rich Internet Application). Această bibliotecă a fost dezvoltată de SAP, companie germană multi-națională de dezvoltare de soluții software pentru business-uri sau relații cu clienții.

Framework-ul SAPUI 5 aduce pe lângă interactivitate foarte mare și un aspect de "business application” oricărei aplicații în care este folosit.

Aceasta este destinat în special părții de client a unei aplicații web. Este un framework deosebit de flexibil, el putând fi folosit împreună cu o sumedenie de alte platforme și tehnologii precum: Apache Tomcat, Cascading Style Sheets (CSS) 3 version, Google WebToolkit (GWT), HTML5 version, Java Platform as a Service (JPaaS), JavaScript (JS), JavaServerFaces (JSF), JavaScript Object Notation (JSON), jQuery, Open AJAX (Asynchronous JavaScript and XML), oData (Open Data Protocol), XML (Extensible Markup Language).

Controalele puse la dispoziție de acest framework sunt construite cu HTML5, CSS 3, jQueryși au capabilități de Ajax. Acestea suportă mai multe teme customizabile și pot fi accesate prin JavaScript. Fiind un framework orientat pe obiecte, controalele se pot declara și instanția ca și în Java urmând ca apoi să li se seteze proprietățile. Totodată acestea pot fi inițializate direct la

instanțiere specificând proprietățile sub formă de JSON.

SAP Fiori este un nou look and feel al framework-ului SAPUI5, o nouă temă a acestuia care aplică principile design-ului modern. Acest UX (user experience) oferă personalizare, responsivitate foarte mare și ușurează interacțiunea utilizatorului cu aplicația simplificând interfața grafică. Framework-ul este proiectat să implementeze design pattern-ul MVC (Model-View-Controller). Programatorul își poate crea ca și model datele sub formă de XML, JSON sau oData pentru a le furniza interfeței grafice.

Întreaga interfață grafică a aplicației prezentate în această lucrare este realizată cu versiunea 1.18 a acestui framework.

4.3. Arhitectura aplicației

Arhitectura aplicației web “Catalog facultate” este structurată pe 3 niveluri:

nivelul de extragere a datelor din baza de date (DAO)

nivelul de business (Servlet-ul și procesarea datelor)

nivelul interfața grafică cu utilizatorul (GUI)

Nivelul de extragere a datelor se bazează pe design pattern-ul DAO (Data Access Object). Acesta oferă o interfață abstractă către orice tip de bază de date fără a expune detaliile conexiunii și crează o separare între nevoile aplicației și datele acesteia. DAO este asociat de obicei cu aplicațiile Java EE care folosesc baze de date relaționale accesate cu ajutorul JDBC.

Nivelul de business preia datele extrase de la DAO și le procesează (convertește sub formă de json) trimițându-le mai departe către intrefața cu utilizatorul sub formă sintetizată.

Servlet-ul comunică direct cu aplicatia prin AJAX call-uri trimițând sau primind date de la aceasta. Partea de server a acestei aplicații este constituită din aceste 2 niveluri.

Partea de client este alcătuită din controale de SAPUI5. Acestea au 2 părti:

view (xml) care ilustrează structura interfeței cu utilizatorul

controller (js) care descrie și definește comportamentul interfeței grafice

Privită in ansamblu, această aplicație respectă principiile design pattern-ului MVC (Model

View Control), astfel:

modelul este constituit din datele extrase din baza de date

controlul este asigurat de partea de server a aplicației

prezentarea este asigurată de interfața grafică cu utilizatorul

Structural, aplicația este alcatuită din 3 proiecte:

LaunchPadMvn – conține partea de server a aplicației (nivelul DAO și Servlet-ul) precum și partea din interfața grafică care înfățișează secțiunile aplicației

StudentsCatalog – conține interfața grafică și funcționalitățile acesteia pentru secțiunea "Catalog studenți"

StudentsCatalogAdmin – conține interfața grafică și funcționalitățile acesteia pentru secțiunea "Administrare catalog"

5. Tehnologii utilizate pentru testarea automată a aplicației

5.1. JUnit

JUnit este un framework cu ajutorul căruia se poate testa codul scris în limbajul Java. Acesta face parte din familia xUnit, o suită de framework-uri pentru testarea codului scris în diferite limbaje de programare. Este un framework open source care permite crearea și rularea de teste. Acesta este constituit dintr-un fișier de tip jar care este încărcat la compilarea codului testat. Framework-ul este localizat în pachetul junit.framework până la versiunea 3.8 sau în pachetul org.junit începând cu versiunea 4.[23]

Ca și celelalte framework-uri din familia xUnit, acesta pune la dispoziția utilizatorilor :

afirmații pentru verificarea rezultatelor așteptate

contexte de test care să partajeze datele comune cazurilor de test

programe executabile pentru rularea testelor

Acest framework este foarte popular deoarece este foarte ușor de folosit, fiind integrat în Eclipse IDE, dar și pentru că se poate integra foarte ușor cu unelte precum Maven pentru rularea automată a testelor.

Pe lângă JUnit sunt o mulțime de framework-uri de testare a codului java: JWalk, TestNG, JTest, Arquillian etc.

Am folosit JUnit pentru a testa codul Java din proiectul "LaunchPadMvn" datorită ușurinței cu care poate fi folosit și a facilităților pe care le pune la dispoziție. Cu ajutorul său am realizat un test de integrare (integration test) și teste de unități (unit tests).

Pentru importarea librăriilor acestui framework în timpul împachetării de către Maven trebuie adăugată în fișierul de configurări pom.xml o dependință la librăriile acestui framework :

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.11</version>

<scope>test</scope>

</dependency>

<dependencies>

Maven este o unealtă care comprimă un proiect, aduce toate dependințele necesare într-un loc comun numit repository și le importă în proiectul respectiv. Orice proiect împachetat cu Maven dispune de un fișier de configurări numit pom (project object model) scris în format xml. Aici se pot defini toate dependințele necesare proiectului precum și procesele ce vor fi realizate în timpul împachetării. [24]

Odată importate, clasele acestui framework se pot accesa și folosi pentru a crea și rula cazurile de test. Acestea pot fi rulate în două moduri:

direct din Eclipse IDE rulând clasa de test (test suite) ca și un test JUnit

testele sunt identificate și rulate în timpul împachetării de către Maven cu comanda "clean install"

Fig. 5.1.1. – Structura proiectului LaunchPadMvn

Pentru identificarea ușoară a testelor ce urmează a fi rulate, acestea trebuie să respecte anumite convenții. Numele testelor trebuie să fie compus din numele clasei testate sufixat de cuvântul "Test". Acest lucru este ilustrat și în figura 5.1.1. Tot aici se poate observa și structura proiectului. Clasele acestuia sunt grupate în pachete localizate în directorul "src/main/java". Testele acestora sunt grupate în aceleași pachete dar în directorul "src/test/java". Păstrând aceste convenții de organizare proiectul va fi mult mai bine structurat iar intreținearea codului său va fi mult mai ușoară.[ 21]

Pentru ca un test implementat cu JUnit să beneficieze de ceea ce pune la dispoziție acest framework , acesta trebuie să extindă clasa TestCase sau orice subclasă a acestuia. Astfel cel ce scrie testul va avea la dispoziție metode specifice precum setUp și tearDown pentru a seta contextul testului dar și afirmații specifice (asserts) pentru a verifica rezultatele testului.[22]

Afirmațiile puse la dispoziție de acest framework sunt:

assertArrayEquals()

assertEquals()

assertTrue() + assertFalse()

assertNull() + assertNotNull()

assertSame() + assertNotSame()

assertThat()

Fiecare caz de test trebuie să conțină anotația "@Test" pentru a fi rulat. De asemenea se obișnuiește ca numele cazului de test să fie compus din numele metodei testate sufixat de cuvântul "Test" la care se adaugă și descrierea cazul testat. Toate aceste convenții se pot observa în exemplul de mai jos. Clasa ce va fi testată se numește GUIUtils.

Pentru a testa funcționalitatea metodei din această clasă s-a scris o clasă de test numită GUIUtilsTest. În cadrul acestei clase este definit un caz de test care este precedat de anotația "@Test" și respectă convențiile de nume.

Metoda testată convertește un șir de caractere într-un obiect de tip dată. În clasa de test este definit un singur caz de test care verifică că obiectul rezultat în urma conversiei nu este null și că data astfel obținută este aceea la care programatorul se așteaptă. În acest exemplu s-ar mai putea adăuga și alte cazuri de test precum verificarea comportamentului metodei în cazul în care șirul de caractere nu este în formatul așteptat.

În fișierul de configurări al uneltei Maven se poate integra o extensie numită "Maven Surefire Plugin" cu configurarea de mai jos:

<plugins>

<plugin>

<artifactId>maven-surefire-plugin</artifactId>

<configuration>

<useSystemClassLoader>true</useSystemClassLoader>

</configuration>

</plugin>

</plugins>

Aceasta va genera în timpul rulării uneltei Maven cu comanda "site:site" o pagină web în format html care va ilustra testele care au fost rulate și rezultatul acestora.

5.2. QUnit

QUnit este un framework cu ajutorul căruia se poate testa codul scris în limbajul JavaScript. Și acesta, asemenea framework-ului JUnit, face parte din familia xUnit. Deși a fost în special utilizat de către proiectul jQuery pentru testarea jQuery, jQuery UI și jQuery Mobile, acesta poate fi utilizat pentru a testa orice cod JavaScript atât pe partea de client cât și pe partea de server.

Acest framework a fost dezvoltat inițial de John Resing ca și parte integrantă a framework-ului jQuery. Acesta a preluat din conceptele unui alt framework numit CommonJS, care ajută la creearea unui ecosistem pentru rularea codul de JavaScript în afara browser-ului, destinat aplicațiilor pe partea de server sau aplicațiilor desktop native.[26]

În 2008 a fost separat de jQuery într-un proiect distinct și a primit numele de QUnit. Acest lucru a permis și altor programatori să își creeze propriile teste pentru aplicațiile lor. În 2009 acesta a fost rescris complet astfel încât să fie un proiect complet separat și să nu mai depindă deloc de framework-ul jQuery pentru interacțiunea cu DOM-ul. [25]

Ceea ce îl diferențiază de alte framework-uri de testare a codului JavaScript este ușurința cu care poate fi utilizat, multitudinea de funcționalități pe care le oferă precum și faptul că acoperă cerințele speciale de testare a codului astfel încât să fie compatibil cu orice browser. Aceste calități l-au făcut să fie utilizat la scară largă într-o multitudine de proiecte. Pe lângă acesta, sunt și alte framework-uri destinate testării codului JavaScript precum: Jasmin, mocha, Buster, Karma etc.

Am folosit QUnit pentru a testa codul scris în limbaj JavaScript din proiectul "StudentsCatalogAdmin". Acesta este un proiect web împachetat cu unealta Maven, care este publicat într-un container web ce joacă rol de server. La fel ca și aplicația, și testele sunt rulate tot în browser. Astfel e nevoie ca și acestea să fie publicate pe server. Pentru ca resursele testelor să fie împachetate și publicate pe server astfel încât să poată fi accesate este nevoie de următoarea configurare în fișierul pom.xml al uneltei Maven. Cu această configurare, testele vor fi publicate în "/test-resources".

<profiles>

<profile>

<id>test.build</id>

<activation>

<activeByDefault>true</activeByDefault>

</activation>

<build>

<resources>

<resource>

<directory>src/test/qunit/src/main/webapp/test-resources</directory>

<targetPath>META-INF/test-resources</targetPath>

</resource>

<resource>

<directory>src/test/qunit/test-resources</directory>

<targetPath>META-INF/test-resources</targetPath>

</resource>

</resources>

</build>

</profile>

</profiles>

Structura proiectului este ilustrată în figura 5.2.1. Directorul "WebContent" conține toate resursele aplicației.Testele sunt localizate în pachetul "src/test/qunit". La fel ca și în cazul JUnit, testele sunt organizate în același mod ca și componentele pe care le testează în directorul "test-files".

Fig. 5.2.1. – Structura proiectului StudentsCatalogAdmin

Directorul "test-resources" conține fișierele de configurări ale testelor. Toate testele ce urmează să fie rulate sunt organizate într-o suită. Suita este definită în 2 fieiere, în fișierul "testsuite.qunit.html" sunt importate resursele framework-ului QUnit iar fișierul "testsuite.qunit.js" conține testele ce for fi rulate. Rezultatele rulări suitei de teste în browser sunt ilustrate în figura 5.2.2. Aici se pot observa toate cazurile de test pentru fiecare fișier testat în parte.

Fig.5.2.2. – Rezultatele rulări suitei de teste în browser

Afirmațiile puse la dispoziție de acest framework sunt:

equal() + notEqual()

notDeepEqual() + deepEqual()

notOk() + ok()

notPropEqual()

notStrictEqual() + strictEqual()

propEqual()

expect()

Fiecare test este definit ca un modul care este inclus în suită pentru a fi rulat. În exemplul de mai jos s-a realizat un test pentru funcțiile din cadrul obiectului Models. Acest obiect conține o funcție care validează dacă un câmp al formularului primit ca parametru are o valoare introdusă. În cazul în care câmpul este gol, acesta va fi colorat cu roșu, un mesaj de avertizare va fi afișat și o variabilă fanion care indică dacă se poate realiza salvarea va fi setată cu valoarea "false".

Testul pentru acest modul se numește ModelsTest și este inclus în suită prin următoarea configurare:

jQuery.sap.require("sap.ui.studCatAdmin.app.test.util.ModelsTest");

Acest test este alcătuit din două cazuri de test: unul pentru cazul în care câmpul este gol și unul pentru cazul când în câmp este introdusă o valoare. Se testează astfel comportamentul funcției "validateInput" în ambele situații. Fișierul care este testat este declarat la începutul testului pentru a avea acces la metoda ce va fi testată. Sunt folosite două afirmații: una pentru a verifica valoarea câmpului și una pentru a verifica valoarea variabilei fanion.

5.3. Mockrunner

Un obiect machetă (mock) este un obiect simulat care imită comportamentul unui obiect real într-un mod controlat. Obiecte machetă sunt folosite la testarea unui modul pentru a examina performanța obiectelor reale. În acest context, un obiect este cea mai mică parte testabilă a unei aplicații. Un obiect machetă folosește aceeași interfață ca elementul de cod pe care il imită.

Aceste obiecte sunt necesare atunci când se testează un modul al aplicației. În acest caz testul vizează strict acel modul iar obiectele machetă ajută la simularea întregului context al testului. Astfel se poate simula și testa comportamentul modului ca și când acesta ar funcționa în timp real în cadrul aplicației.

Pentru a construi obiectele de tip machetă am folosit framework-ul Mockrunner. Acesta extinde framework-ul JUnit și simulează comportamentul necesar al obiectelor și metodelor fără a mai fi nevoie să fie chemată infrastructura reală. Este foarte rapid și oferă posibilitatea manipulării tuturor claselor și obiectelor machetă în orice etapă a testelor. Am folosit două module ale acestui framework: unul pentru a simula conexiunea JDBC (Java Database Connectivity) prin care se extrag datele din baza de date și unul pentru a simula comportamentul unui Servlet. Pentru a include librăriile acestor module este nevoie ca următoarele două dependințe să fie adăugate în fișierul de configurări al uneltei Maven:

<dependencies>

<dependency>

<groupId>com.mockrunner</groupId>

<artifactId>mockrunner-jdbc</artifactId>

<version>1.0.6</version>

</dependency>

<dependency>

<groupId>com.mockrunner</groupId>

<artifactId>mockrunner-servlet</artifactId>

<version>1.0.6</version>

</dependency>

</dependencies>

În cazul modulului JDBC, am folosit astfel de obiecte machetă la testarea funcționalității de prelucrare a datelor extrase din baza de date. Scopul testului în acest caz a fost să verifice modul în care sunt prelucrate datele primite, nu să verifice modul în care driver-ul specific bazei de date furnizează datele respective. Folosind acest framework, testele au devenit independente de baza de date, putând fi rulate oricând și pe orice mașină. Datele care ar fi trebuit extrase din baza de date sunt gestionate și controlate de cel care crează testul și orice alterare a acestora în partea de procesare a lor este imediat observată.

Am folosit modulul Servlet pentru a simula comportamentul Servlet-ului care trimite și primește date de la interfața grafică cu utilizatorul. Scopul testelor a fost să verifice felul în care erau prelucrate datele pentru a fi trimise în format json interfeței și structura și formatul datelor primite de la interfață. Acțiunile post și get, funcționalități ale Servletului, nu au făcut obiectul acestui test. Astfel acestea au fost simulate cu acest framework. Testul creat a devenit independent de un container web sau un server pe care să fie publicat acel Servlet, putând fi rulat oricând și pe orice mașină.

5.4. SinonJS

Un spion de testare (test spy) este o funcție care înregistrează argumente, valoarea returnată, valoarea contextului this și eventualele excepții aruncate pentru toate apelurile unei metode. Un spion de test poate fi o funcție anonimă sau poate îngloba o funcție existentă.

Framework-ul SinonJS permite creare de astfel de spioni de testare și de module vide pentru testarea codului scris în limbajul JavaScript.

Am folosit acest framework pentru a instanția controller-ele testate și pentru a simula metodele care construiesc contextul testului. Astfel am putut să simulez funcționarea în condiții normale a metodelor testate pentru a le verifica modul de funcționare.

Pentru configurarea acestui framework trebuie referite următoarele librării în suita testelor QUnit "testsuite.qunit.html":

<scripttype="text/javascript" src="../resources/sap/ui/thirdparty/sinon.js"/>

<scripttype="text/javascript"

src="../resources/sap/ui/thirdparty/sinon-qunit.js"/>

5.5. Cobertura

Acoperirea codului (code coverage) este o unitate de măsură utilizată în testarea software. Aceasta descrie gradul de acoperire a codului sursă a unui program de către teste. A fost printre primele metode inventate pentru testarea software sistematică. Nu există un procent fix pentru proporția în care un cod trebuie să fie acoperit de teste. Această valoare este stabilită în funcție de necesitățile și țelurile fiecărei organizații.

Trebuie însă să se aibă în vedere faptul că deși un cod ar putea avea un procent de acoperire de 100%, nu înseamnă că acel cod va funcționa corect. Procentul de acoperire nu reflectă lipsa de erori în acel cod. Este foarte important ceea ce se testează pentru acel cod iar acest lucru se realizează redactând cazuri de test cât mai complexe.

Procentul de acoperire al codului trebuie să aibă doar valoare orientativă, să semnalizeze celui care crează teste că acel cod a fost testat și să furnizeze informații despre stadiul testării aplicației.

Am folosit framework-ul Cobertura pentru a realiza rapoarte de acoperire a codului pentru codul scris în limbajul Java în proiectul "LaunchPadMvn". Această unealtă se integrează cu ajutorul uneltei Maven adăugând următoarea configurare în fișierul pom.xml:

<reporting>

<plugins>

<plugin>

<groupId>org.codehaus.mojo</groupId>

<artifactId>cobertura-maven-plugin</artifactId>

<version>2.7</version>

</plugin>

</plugins>

</reporting>

Aceasta generează un raport în fomat html în momentul în care Maven este rulat cu comanda "site:site" sau " cobertura:cobertura-integration-test". Acest raport este generat în fișierul "target" din proiectul pentru care este rulat. Un fragment din raport poate fi observat în figura 5.5.1. Selectând fiecare fișier în parte din acest raport se poate observa hașurat cu roșu codul care nu este acoperit de teste.

Fig. 5.5.1. – Raportul de acoperire al codului realizat cu Cobertura

Raportul de acoperire pentru exemplul din capitolul 5.1.este ilustrat în figura 5.5.2. Aici se poate observa că pentru această metodă a fost realizat un singur caz de test și metoda a fost apelată o singură dată din teste. Acest lucru este simbolizat de cifrele de "1" hașurate cu verde.

De asemenea se poate observa că testul nu a simulat și situația în care parametrii metodei respective ar fi invalizi iar conversia lor ar genera o eroare. Astfel porțiunea de cod pentru prinderea erorii nu este atinsă de test, ea fiind hașurată cu roșu.

Fig. 5.5.2. – Fragment din raportul de acoperire al codului

5.6. Blanket.js

Această unealtă este destinată măsurării procentului de acoperire al codului scris în limbaj JavaScript. Este destinată folosirii împreună cu testele realizate cu framework-ul QUnit.

Am folosit această uneltă pentru măsurători în proiectul "StudentsCatalogAdmin".

Pentru a putea fi folosită, trebuie adăugat codul sursă al acestei unelte (blanket.js) în proiectul respectiv (figura 5.2.1.). În suita care va rula testele QUnit (testsuite.qunit.html) trebuie adăugată o referință către acest script împreună cu referințele către fișierele pentru care se va măsura procentul de acoperire:

<scriptsrc="blanket.min.js"></script>

<scriptsrc="../util/Models.js"data-cover></script>

<………restul testelor……..>

<scriptsrc="../util/Formatter.js"data-cover></script>

Raportul de acoperire al codului ilustrat în figura 5.6.1. poate fi pornit bifând opțiunea "Enable coverage". Acesta va fi generat în timpul rulării testelor și va apărea împreună cu rezultatul rulării acestora in browser.

Ca și în cazul uneltei Cobertura, fiecare fișier din acest raport poate fi selectat în parte pentru a vedea porțiunile de cod acoperite de teste.

Fig. 5.6.1. – Raportul de acoperire al codului realizat cu Blanket.js

6. Managementul procesului de testare

Procesul de testare automată presupune un efort de management deosebit. Ponderea cheltuielilor pentru testare reprezintă între 30% și 50% din totalul cheltuielilor pentru dezvoltarea unei aplicații software. Din această cauză managementul acestui proces este deosebit de important iar un management precar ar putea duce la eșuarea întregului proiect.

Procesul de management al testării începe încă din faza de analiză a aplicației și continuă în toate etapele de dezvoltare. În diagrama din figura 6.1 se pot observa etapele procesului, ordinea și frecvența acestora, precum și locul central pe care îl ocupă managementul defectelor și serviciile.

Fig.6.1- Managementul testării automate [13]

Managementul procesului de testare trebuie să țină cont de mai multe aspecte precum:

locul procesului de testare în cadrul ciclului de dezvoltare al unui produs software

definirea etapelor propriu-zise ale procesului de testare

folosirea și achiziționarea de instrumente care să faciliteze acest proces

Fiecare din acești factori este deosebit de important și trebuie stabilit înainte de începerea implementării efective a produsului software. Orice alegere greșită în această etapă poate să pericliteze întregul proces. Acești factori vor fi detaliați în capitolele ce urmează.

6.1. Testarea în cadrul ciclului de dezvoltare software

Proiectarea aplicațiilor software de dimensiuni mari, dezvoltate în cadrul unei echipe, nu se face trecând direct la implementarea programului, ci urmează etape bine stabilite . Se pot diferenția mai multe modele de dezvoltare fiecare având atât avantaje cât și dezavantaje.

Indiferent de modelul care se folosește, este necesară o testare foarte bună, întrucât calitatea si succesul produsului software depind de aceasta.

6.1.1. Modelul cascadă

Acest model presupune ca procesul de dezvoltare al aplicațiilor software sa fie alcătuit din următoarele etape: specificarea cerințelor, analiză, proiectare, implementare, testare și întreținere. În figura 6.1.1.1. este prezentat grafic modelul clasic de dezvoltare software .

Fig. 6.1.1.1 – Modelul clasic de dezvoltare software cascadă [7]

Avantajele acestui model sunt:

este simplu și ușor de utilizat

fazele și procesele sunt terminate pe rând

bun pentru proiectele mici unde cerințele sunt bine înțelese de la început

Dezavantaje lui sunt:

modificarea cerințelor este foarte greu de gestionat

nu se pot produce prototipuri decât foarte tarziu

În cadrul ciclului de dezvoltare software există intercalate și etape de testare cum ar fi: testarea de module, testarea de integrare, testarea de sistem, testarea de acceptare. Corespondența dintre fazele ciclului de dezvoltare software și etapele testării este prezentată în figura 6.1.1.2.

 Fig. 6.1.1.2. – Nivelele testării în cadrul ciclului de dezvoltare software [1]

6.1.2. Modelul V

Modelul V arată diferitele stagii în dezvoltare și testare, precum și relațiile dintre acestea. Se uitilizează patru nivele de testare pentru cele patru nivele de dezvoltare. În practică, se pot întâlni mai puține nivele de testare și dezvoltare, depinzând de proiect. Acest model este ilustrat în figura 6.1.2.1.

Acest model este mai bun decât modelul în cascadă din punct de vede al testării și asigurării calității deoarece planul de testare este făcut încă de la început. Acesta are următoarele dezavantaje:

modificarea cerințelor este foarte greu de gestionat

nu se pot produce prototipuri timpurii

Fig. 6.1.2.1.– Modelul de dezvoltare V [9]

6.1.3. Modelul de dezvoltare iterativ-incremental

Acest model se bazeaz pe o idee foarte simpl: dac un sistem este prea complex pentru a fi neles, conceput sau realizat ntr-o singur faz este mai bine s fie realizat n mai multe faze, prin evoluie.

Acesta presupune împărțirea proiectului într-o serie de subproiecte mici, iar fiecare subproiect urmărește un model V detaliat anterior. Figura 6.1.3.1. ilustrează modul în care se succed etapele de dezvoltare în cadrul acestui model. Astfel pentru fiecare activitate de dezvoltare corespunde o activitate de testare. Fiecare nivel de testare are obiective specifice pentru acel nivel al aplicației.

Acesta are urmatoarele avantaje:

analiza timpurie a riscurilor

revizitarea planurilor

calitate pe nivele și o mai mare motivație

posibilitatea de furnizare timpurie a prototipurilor

testarea se realizează în fiecare iterație

feedback-ul utilizatorilor este distribuit pe întreg parcursul dezvoltării

în cazul apariției unor schimbări în cerințe acestea pot fi încoporate în urmatorul prototip

Fig. 6.1.3.1. – Modelul de dezvoltare iterativ-incremental [8]

Pentru realizarea aplicației "Catalog facultate" am aplicat modelul iterativ-incremental. Aplicația a fost realizată în 3 iterații. Aceste iterații, împreună cu task-urile pe care le conțin sunt ilustrate în Anexa 1. Aici se poate observa succesiunea temporară a task-urilor în cadrul unei iterații precum și distribuția task-urilor de testare în raport cu cele de implementare.

Pentru fiecare task implementat s-au realizat atât teste automate cât și teste manuale. Testele automate s-au rulat înainte de fiecare commit pentru a verifica dacă funcționalitățile noi implementate nu influențează funcționalitățile existente. Testarea manuală este de preferat să fie realizată de altă persoană față de cea care a implementat funcționalitatea respectivă. Pentru că, datorită experienței diferite, există șanse mari ca cele două persoane să vadă abordări diferite de testare a task-ului respectiv. Totodată există posibilitatea ca cel care a implementat task-ul respectiv să se limiteze doar la cazurile de test pe care le-a identificat în timpul implementării, neglijând alte posibile cazuri de test. Astfel se acoperă o plajă cât mai largă de cazuri de test.

La sfârșitul întregii iterații se reia rularea tuturor testelor și se realizează o testare manuală de regresie pentru toate funcționalitățile pentru a se asigura că prototipul astfel obținut corespunde cerințelor.

6.2. Etapele procesului de testare

Fazele procesului de testare, ilustrate și ȋn figura 6.2.1. sunt:

Planificarea și controlul testelor

Analiza și design-ul testelor

Implementarea și execuția testelor

Evaluarea criteriilor de terminare și raportare

Activități de finalizare a testelor

Fig. 6.2.1. – Fazele procesului de testare[5]

6.2.1. Planificarea testării

Planificarea testelor se realizează în strânsă legătură cu planificarea derulării întregului proiect. În această faza se alocă resurse, specificându-se bugetul și se stabilește perioada de timp în care se va derula procesul de testare. Pe baza acestor criterii se planifică detaliată în detaliu întregul proces de testare.

Planificarea testării are scopul de a specifica ce anume trebuie să se testeze și modul în care să se realizeze testarea, astfel încât acest proces să se încadreze în limitele resurselor alocate. Planificarea testării se concretizează într-un document numit plan de test, pe baza căruia se desfășoară celelalte faze ale testării și care specifică obiectivele testării.

Atribuțiile importante ale acestei faze sunt:

definirea strategiei de testare

determinarea scopului și riscurilor

determinarea abordării testării (tehnici, procentul de acoperire a testelor,echipe implicate)

programarea implementării, execuției și evaluarea testelor

definirea sistemul de testare (hardware și software)

estimarea efortului de testare

Planul de test cuprinde:

aria de acoperire a testelors

resursele umane necesare și responsabilitățile fiecărui membru al echipei de testare

timpul alocat testelor

lista echipamentelor care trebuie achiziționate precum și modul de configurare a mediului specific aplicației

modul de creare și managementul datelor de test

criteriile de acceptare a testelor care determina momentul în care se va încheia testarea

6.2.2. Controlul testării

Este o activitate continuă de comparare a progresului actual al testării cu planul inițial de test și raportarea stării actuale pentru a observa și corecta deviațiile de la plan. Acest proces implică luarea măsurilor necesare pentru a se respecta planul inițial și pentru a îndeplini obiectivul proiectului.

6.2.3. Analiza și design-ul testării

În etapa de analiză se realizează următorii pași:

echipa de testare identifică scopurile, obiectivele și strategiile testării

metodele de verificare sunt documentate pentru a putea fi urmărite și sunt asociate cerințelor sistemului sau cazurilor de utilizare

se analizează cerințele testelor

cerințelor testelor se asociază cerințelor sistemului sau ale cazurilor de utilizare

se realizează o corelare între tehnicile de testare și declarațiile cerințelor testelor

Analiza cerințelor pentru testare este un proces foare important. Cerințele testării trebuie să fie identificate și documentate astfel încât toate persoanele implicate în procesul de testare să fie conștiente de scopul acestuia. Analiza se realizează în funcție de faza de testare. Astfel se poate identifica o abordare bazată pe comportament și o abordare structurală.[4]

După faza de analiză urmează faza de proiectare care constă în următorii pași:

definirea tehnicilor de testare utilizate

definirea arhitecturii de test

definirea procedurilor de test

luarea deciziei de automatizare a anumitor teste și de testare manuală a altor componente

asocierea datelor de test astfel încât fiecare cerință pentru datele de test să se reflecte pentru fiecare procedură de test

6.2.4. Implementarea și execuția testelor

În etapa de implementare a testelor se construiesc, pe baza rezultatelor fazei de proiectare, cazurile de test și procedurile de test.

Cazurile de test descriu atât parametrii de intrare cât și rezultatele așteptate după execuția codului verificat utilizând acei parametri. Cu cât un caz de test este mai complet și mai complex, cu atât șansele de descoperire a erorilor cresc. Procedurile de test identifică toți pașii necesari pentru proiectarea si executarea cazurilor de test.

Pentru a putea începe procesul de testare este necesară configurarea arhitecturii dezvoltării testelor.

Tot în această etapă trebuie să se identifice standardele pe care se bazează procesul de elaborare al secvențelor de test. Acestea stabilesc convențiile de scriere a programelor de test (alinieri, comentarii, prefixe pentru date).

Secvențele de test se implementează în limbajele specifice mediilor de testare sau în limbaje de programare evoluate în functie de tehnolgiile alese.

În etapa de execuție a testelor sunt rulate efectiv secvențele de test. Execuția secvențelor de test se realizează pe cât posibil în mediul specific aplicației iar dacă nu este posibil, acest mediu este simulat.

În figura 6.2.4.1.este prezentat fluxul procesului de execuție și evaluare a testelor pentru testarea la nivel de modul, bazată pe specificații. Conform acestei scheme, faza de rulare a testelor are ca intrări programul care trebuie testat și datele acestuia de intrare. Ieșirile fazei de execuție a testelor sunt rezultatele testelor care sunt comparate cu ieșirile așteptate. [4]

Fig. 6.2.4.1.– Fazele de execuție și evaluare pentru testarea de module [4]

6.2.5. Evaluarea criteriilor de terminare și raportare

În această etapă se evaluează rezultatele execuției secvențelor de test pentru a determina dacă produsul a trecut toate testele cu succes. Evaluarea acestora se face de către un oracol. Oracolul poate fi o persoană sau un instrument automat, care are capacitatea să determine pe baza specificațiilor dacă rezultatele execuției testelor sunt corecte sau nu.[4]

Un jurnalul de test ar trebui să conțină:

versiunile software-ului și testelor rulate

specificațiile care au fost folosite ca bază a testelor

cronometrarea testelor

rezultatele testelor – rezultatele propriu-zise dar și rezultatele așteptate

detaliile defectelor

Din revizuirea jurnalului de test trebuie să rezulte dacă sunt necesare și alte teste sau dacă criteriile de terminare ale testelor trebuiesc modificate. [5]

6.2.6. Activități de finalizare a testelor

Această etapă constă în mai multi pași:

verificarea faptului că produsul rezultat este conform planurilor

finalizarea și arhivarea testelor și mediilor de testare

determinarea situației în care testarea este finalizată și proiectul se poate închide

actualizarea și înregistrare tuturor documentelor specifice testării într-un sistem de control al versiunii

6.3. Instrumente pentru managementul procesului de testare

Un subiect din ce în ce mai sensibil în dinamica business-ului din zilele noastre este calitatea produselor care sunt oferite. Presiunea acționarilor, a managementului, a clienților și a concurenței de a strânge timeline-urile proiectelor are, nu de puține ori, un impact negativ asupra calității. În ajutorul aceste probleme vin o mulțime de unelte care ajută la gestionarea eficientă a acestui proces.

Acestea ajută la obținerea datelor despre calitatea produsului în timp real pe parcursul proiectului, la organizarea proiectului, la refolosirea testelor și cazurilor de test. Totodată acestea ajută și la determinarea direcției în care se îndreaptă produsul. Astfel încât eventuale decizii de corectare să fie luate la timp sau deciziile de release a produsului să se facă în cunoștință de cauză din punctul de vedere al calității produsului.[27]

Un astfel de instrument folosit consecvent și consistent ajută la economisirea timpului prin reutilizarea testelor, prin automatizarea raportărilor și a unor teste, la menținerea trasabilității problemelor de calitate, la dezvoltarea unui plan pentru îndeplinirea pragurilor de calitate agreate cu clientul sau asumate intern.

Pe piață există o ofertă foarte diversificată de astfel de tool-uri. Acestea trebuie alese în funcție de necesitățile fiecărui proiect, de infrastructura existentă, de sistemele cu care se dorește sa fie integrat și de banii disponibili.

6.3.1. Microsoft Project 2013

Pentru managementul taks-urilor de testare și pentru calcularea resurselor necesare proiectului am folosit unealta Microsoft Project 2013. Această unealtă este deosebit de utilă și ușurează foarte mult procesul de management al unui proiect permițând:

crearea, planificarea și asignarea de task-uri resurselor disponibile

rezolvarea suprapunerilor de task-uri și de rezolvarea problemei lipsei de resurse

obținerea unei viziuni de ansamblu asupra stadiului tutuor task-urilor

generarea și personalizarea de rapoarte provind costuri, task-uri, resurse

Cu ajutorul acestei unelte am realizat managementul task-urilor proiectului "Catalog facultate", ilustrat în diagrama Gantt din Anexa 1. Totodată am generat și rapoartele de costuri și de alocare a orelor din Anexele 2 și 3.

6.3.2. Cobertura si Blanket.js

Pentru a putea monitoriza procentul de acoperire al codului (code coverage) de teste am folosit două unelte specifice fiecărui limbaj în care este implementată aplicația:

Cobertura pentru codul Java

Blanket.js pentru codul JavaScript

Modul acestora de funcționare și de configurare a fost descris în capitolul anterior.Valoarea procentului pentru proporția în care un cod trebuie să fie acoperit de teste este stabilită de fiecare organizație în parte în funcție de necesitatiile aplicației testate. Acest procent de acoperire este doar orientativ. Un procent de 100% nu înseamnă lipsa tuturor erorilor în codul testat.

Am ales pentru acest studiu de caz ca limita de la care testele să fie acceptate din punct de vedere al acoperirii lor să fie de 60%. Am ales această valoare pentru că fișierele acestei aplicații nu conțin doar implementarea funcționalităților ci și implementare a unor pattern-uri de design iar aceastea presupun adăugarea de cod suplimentar pentru separarea diferitelor nivele de logică ale aplicației, acest cod neinfluențând funcționalitatea aplicației.

Rapoartele generate de aceste unelte sunt deosebit de importante pentru determinarea stadiului în care codul este testat și a calității acestuia.

6.3.3. Assembla

Pentru un mai bun management al reviziilor am folosit o unealtă numită Assembla. Aceasta este o unealtă online care, după crearea unui cont, oferă utilizatorilor săi o multitudine de servicii pentru o bună gestionare a unui produs software și a echipelor care lucrează la acel produs. Majoritatea serviciilor oferite sunt contra cost.

Am folosit pentru acest proiect serviciul lor gratuit de SVN. Acesta presupune stocarea proiectului pe server-ele Assembla și păstrarea evidenței tuturor modificărilor resurselor acestui proiect (reviziilor). Acesta unelta este esențială atunci când la un proiect lucrează mai multe persoane.

Fig. 6.3.3.1. – Istoricul modificărilor din proiectele aplicației "Catalog facultate"

Fiecare programator are o copie locală a proiectului pe care îl poate modifica și fiecare modificare a acestuia poate fi "comisă" pe proiectul stocat pe server astfel încât toată lumea să aibă acces la ea. Toate modificările împreună cu autorul lor și data la care au fost comise sunt luate în evidență, obtinandu-se astfel un istoric al proiectului. O astfel de evidență a modificărilor este ilustrată în figura 6.3.3.1.

Folosind o astfel de unelta se pot monitoriza foarte ușor toate funcționalitățile implementate într-un anumit interval de timp și se pot păstra prototipurile obținute în fiecare iterație sub formă de "branch-uri".

6.3.4. TestLodge

Pe piața tehnologiilor IT se găsesc o multitudine de soluții web foarte bune pentru managementul testării software. Cele mai renumite astfel de instrumente sunt: SpiraTest, TestRail și TestLodge. Acestea permit controlul, monitorizarea și organizarea în mod eficient a efortului de testare.

Avantajele lor sunt:

nu se pierde timp cu instalarea, configurarea și mentenanța lor (accesul la ele facandu-se doar creând un cont și accesând o aplicație web)

interfața este foarte simplă și intuitivă

multitudinea de funcționalități pe care le pun la dispoziție (managementul rapoartelor, cerințelor, testelor și task-urilor de testare)

posibilitatea de a fi integrate cu o mulțime de unelte de gestiune a proiectelor (Jira, Assembla etc)

Am folosit pentru managementul testării manuale al aplicației „Catalog facultate” unealta TestLodge. Această unealtă nu este gratuită dar oferă posibilitatea creării și utilizării unui cont de probă timp de 30 de zile.

Este o unealtă în special destinată departamentelor de QA (Quality Assurance). Aceasta permite gestionarea persoanelor implicate în procesul de testare și definirea de permisii pentru aceștia. Fiecărui testor îi pot fi asignate suite de teste iar acesta poate avea în orice moment o evidență clară a ceea ce testează sau urmează să testeze. Cordonatorul acestui departament poate avea o viziune de ansamblu asupra stadiului curent al procesului de testare.

Creând un cont, se va crea automat un site pentru proiectul ce urmează să fie testat. Acest site oferă o viziune de ansamblu asupra întregului proces de testare precum și acces

la toate funcționalitățile pe care TestLodge le pune la dispoziția testorilor sau celor care supervizează procesul de testare.

Site-ul creat pentru aplicația prezentată în acesta lucrare este:

http://studentscatalog.testlodge.com/

Interfața deosebit de intuitivă mi-a permis să creez cu ușurință un plan de test (test plan) numit „Testare secțiune de administrare”. Aici este definit ceea ce trebuie să se testeze, criteriile de acceptanță, termenele limită, responsabilitățile fiecărui testor etc. Acest plan conține suitele de teste. Pentru acest proiect am creat 4 astfel de suite. Acestea împreună cu planul de test sunt ilustrate în figura 6.3.4.1.

Fig. 6.3.4.1. – Planul de test și suitele de teste asociate acestuia

Fiecare suită conține la rândul ei mai multe cazuri de test care descriu ce anume trebuie testat, pașii pe care trebuie să îi parcurgă cel care testează precum și rezultatele la care trebuie să se aștepte acesta. Figura 6.3.4.2. ilustrează cazurile de test din suita „Adăugare student”. Se poate observa că s-au creat 4 cazuri de test:

CNP invalid

date incomplete

CNP invalid si date incomplete

date valide

Fig. 6.3.4.2. – Cazurile de test din cadrul suitei "Adăugare student"

Aceste suite pot fi rulate cu ușurință de persoana căreia îi sunt asignate. În urma testării manuale, testorul trebuie să specifice dacă testul a eșuat sau nu. La finalul rulării tuturor testelor din cadrul suitei se generează un raport. Un exemplu de astfel de raport este ilustrat în figura 6.3.4.3. Aici se poate observa că toate cele 4 cazuri de test ale suitei „Adăugare student” au fost procesate:

2 au trecut

1 a eșuat

1 a fost ignorat

Aceste suite de teste se pot reutiliza și rula ori de câte ori este nevoie. Acest fapt duce la standardizarea procesului de testare indiferent de testorul care le rulează.

Fig. 6.3.4.3. – Rezultatele rulării testelor din suita "Adăugare student"

6.4. Managementul costurilor de testare

Fiecare proiect are alocat un anumit buget. Pentru a obține un produs de calitate este foarte important ca o parte din acest buget să fie alocată costurilor procesului de testare. Cu cât managementul procesului de testare este mai eficient, cu atât costurile vor fi mai mici.

Acest buget alocat testării trebuie să fie stabilit încă din etapa de analiză a proiectului și trebuie să prevadă:

costurile dezvoltării și realizării testelor

cheltuieli cu personalul (atât testori cât și programatori care vor redacta testele automate) cheltuieli pentru instrumente de asistare și de management al procesului de testare

cheltuieli pentru echipamente

Pentru stabilirea bugetului alocat testării se construiesc modele de estimare a efortului de testare și a costurilor aferente proiectului. Pentru acestea trebuie să se ia în considerare nivelul estimat al complexității software și structura proiectului.

Costul testării ocupă un procent important din bugetul total al dezvoltării aplicațiilor software. Statistic s-a demonstrat că acesta ocupă în medie 29% din costurile unui proiect[28]. Proporția sa este ilustrată în graficul din figura 6.4.1. Aici sunt evidențiate costurile asociate fiecărei faze specifice procesului de dezvoltare software.

Fig. 6.4.1. – Repartiția statistică a costurilor asociate fazelor specifice dezvoltării software

Identificarea costurilor generate de procesul de testare este foarte importantă pentru minimizarea costului întregului proiect software. Prin analizarea cu atenție a surselor cheltuielilor procesului de testare, se pot găsi modalități pentru reducerea acestora. Astfel, scăderea cheltuielilor de testarea se poate realiza prin [12]:

alegerea unui personal calificat care să se ocupe de testare

automatizarea procesului de testare

documentarea corespunzătoare a întregii activității de testare

reutilizarea testelor

începerea testării încă din fazele de început ale ciclului de dezvoltare software pentru depistarea timpurie a eventualelor probleme

alegerea unui criteriu optim de oprire a testării

Graficul din figura 6.4.2. exemplifică diferența dintre testarea manuală și cea automată în ceea ce privește costurile pe termen lung ale procesul de testare. Astfel se poate observa că pe termen lung, testarea manuală este mult mai costisitoare decât testarea automată.

Pentru obținerea acestui grafic s-a considerat că efortul necesar pentru automatizare este egal cu cel pentru execuția manuală a testelor (10 minute). Executarea testelor automate deja create durează doar 1 minut în comparație cu retestarea manuală care durează 10 minute. Astfel după 5 iterații (Release 6) timpul total de testare manuală va fi de 60 minute iar cel de testare automată va fi de 15 minute.

Fig. 6.4.2. – Efortul și costurile testării automate/manuale

Costurile estimate ale testării aplicației "Catalog facultate" sunt ilustrate în raportul de costuri realizat de unealta Microsoft Project 2013 din Anexa 2.

Conform acestui raport, pentru implementarea acestei aplicații s-au consumat 440 de ore. Dintre acestea 256 au fost alocate procesului de implementare și 184 procesului de testare. Considerând salarul unui programator ca fiind 10$ pe oră și cel al unui testor 8$ pe oră, costurile proiectului s-au ridicat la 4260$. Din aceste costuri 1700$ au fost alocați doar procesului de testare.

Se poate observa astfel că procesul de testare a consumat 40% din bugetul total alocat proiectului. Graficul din figura 6.4.3. ilustrează comparativ aceste proporții. Deși testarea manuală pare mai ieftină decât cea automată, pe termen lung testarea automată nu va mai necesita costuri suplimentare spre deosebire de cea manuală.

Fig. 6.4.3. – Proporția costurilor de testare ale aplicației "Catalog facultate"

6.5. Managementul timpului alocat testării

Proiectul implementării aplicației "Catalog facultate" a început în data de 2 Martie 2015 și s-a încheiat în data de 22 Mai 2015 (conform diagramei Gantt din Anexa 1), acesta beneficiind de 440 de ore de lucru.

Raportul din Anexa 3 ilustrează modul în care au fost distribuite aceste ore. Conform acestui raport, efortul de testare manuală a fost concentrat în 70 de ore, cel de testare automată în 114 iar cel de implementare în 256 de ore. Astfel procesul de testare a consumat 42% din timpul total alocat acestui proiect. Aceste proporții sunt ilustrate și în graficul din figura 6.5.1.

Efortul de testare automată (114 ore) și manuală (70 ore) s-a concretizat în:

teste manuale – 12 cazuri de test grupate în 4 suite

teste automate pentru codul JavaScript – 14 cazuri de test grupate în 6 teste

teste automate pentru codul Java – 24 de cazuri de test grupate în 4 teste (ilustrate în Anexa 4)

Fig. 6.5.1. – Proporția orelor alocate testării aplicației "Catalog facultate"

Astfel codul Java a fost acoperit de teste în proporție de 71.8% iar codul JavaScript în proporție de 66.49%. Proporția în care fiecare fișier este acoperit de teste pentru testele Junit este ilustrată în figura 6.5.3. iar pentru Qunit în figura 6.5.2.

Am ales ca pragul de acceptanță să fie 70% pentru codul Java datorită faptului că implemetarea design pattern-urilor precum DAO necesită adăugarea de clase suplimentare care nu au impact direct asupra funcționalității aplicației, cod care nu necesită testare.

Totodată, pentru codul JavaScript am ales ca pragul să fie de 60% deoarece controller-ele aplicației conțin multe inițializări ale obiectelor framework-ului sau funcții specifice care nu fac obiectul testării acestui proiect. Acestea au fost testate în prealabil de cei care au implementat framework-ul SAPUI 5.

Fig. 6.5.2. – Proporția în care codul fișierelor JavaScript este acoperit de teste

Fig. 6.5.3. – Proporția în care codul claselor Java este acoperit de teste

Concluzii

Testarea este pricipalul proces fără de care nu se poate de realizat un produs software de calitate. Activitatea de testare este esențială, dar și scumpă și foarte laborioasă. Acest proces trebuie să înceapă încă din etapa de analiză a specificaților proiectului și să se desfășoare pe tot parcursul proiectului. Procesul de testare ajunge să ocupe aproape tot atâta timp cât procesul de implementare a produsului și din acest motiv trebuie gestionat în cel bun mod posibil.

Testare automată și manuală, cele două tipuri principale de testare, sunt deosebit de importante. Majoritatea proiectelor folosesc combinat ambele tipuri deoarece fiecare tip compensează lipsurile celuilalt. Este greu de determinat care ar trebui să fie ponderea fiecărui tip în procesul de testare. Acesta este determinată de tipul și necesitățile proiectului respectiv.

În studiul de caz prezentat în acesta lucrare, testarea automată a consumat 27% din buget și 26% din timpul alocat proiectului. Testarea manuală a consumat doar 16% din timpul alocat proiectului și 13% din bugetul alocat acestuia.

Deși testarea automată pare mai costisitoare decât cea manuală, pe termen lung aceasta nu va mai necesita nici un cost suplimentar spre deosebire de cea manuală.

După cum s-a putut observa în studiul de caz, testarea a consumat 40% din bugetul alocat acestui proiect, astfel estimarea încă din faza de planificare a proiectului a acestor costuri este deosebit de importantă. O estimare superficială și eronată a acestor costuri ar putea duce la situația în care să nu existe suficiente fonduri pentru finalizarea proiectului.

Întregul proces de testare este foarte amplu și greu de gestionat. Pe piață există o mulțime de unelte care ajută la managementul acestui proces. În acest studiu de caz am încercat să folosesc unelte atât pentru testare automată cât și pentru testare manuală și am constatat că fără acestea întregul proces s-ar fi desfășurat haotic și orice estimare de timp sau de buget ar fi fost imposibilă.

O eventuală direcție de dezvoltare a acestui studiu de caz ar fi utilizarea și altor tipuri de teste automate care să verifice modul în care este afișată interfața grafică (precum Selenium, JMeter etc). Totodată s-ar putea folosi unelte care să realizeze procesul de CI (Continous Integration). O astfel de uneltă ar fi Jenkins. Aceasta ar permite rularea testelor automate fără intervenția operatorului uman după fiecare modificare a codului, economisind astfel timp și descoperind eventualele erori foarte devreme.

Bibliografie

[1]http://www.testare-software.ase.ro/articole/test2.htm

[2]Ionescu Augustin Iulian – Curs 2010 – Testarea sistemelor de calcul si a retelelor

[3] http://www.cs.ubbcluj.ro/~mfrentiu/Lectures/VerVal/lectii/C9%20~%20VvSs.pdf

[4] http://www.biblioteca-digitala.ase.ro/biblioteca/carte2.asp?id=408&idb=

[5]http://stst.elia.pub.ro/news/IS/TEME_IS_2012_13/1_MiuMa_HereaCr_3GheorgheCo_PetreRa_ParaschivRa_NegreiAl_TeodorascuPa_Test%20PSW_ver_val_v3.pdf

[6]http://www.testingexcellence.com/software-testing-definitions/

[7] Damian Nae Paun – Tehnici de testare software

[8]http://www.google.ro/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCMQFjAA&url=http%3A%2F%2Fandrei.clubcisco.ro%2Fcursuri%2F3ip%2Fcurs%2F2.2_Modele_ale_procesului_de_dezvoltare.doc&ei=3vJhVf3WOOLjywOuioGoAg&usg=AFQjCNFXjFXdVkFJo-97NiVX3pFgZbh8Bw&sig2=ocqiRZZIaUsl66tyHDZeNw&bvm=bv.93990622,d.bGQ&cad=rja

[9]http://www.shiva.pub.ro/PDF/TEST/Testarea%20software%20si%20asigurarea%20calitatii%20-%20curs1.pdf

[10] http://thor.info.uaic.ro/~dlucanu/cursuri/css/resurse/Saptamana5.pdf

[11]http://en.wikipedia.org/wiki/Test-driven_development

[12]http://revistaie.ase.ro/content/30/ivan-pocatilu.pdf

[13]http://www.scribd.com/doc/72039973/Testarea-Automata#scribd

[14] http://www.pawlan.com/monica/articles/j2eearch/

[15] http://docs.oracle.com/cd/B14099_19/web.1012/b14017/overview.htm

[16]http://www.pawlan.com/monica/articles/j2eearch/

[17]http://ro.wikipedia.org/wiki/Servlet

[18]http://www.softwaretesting.ro/Romana/Files/ManualVsAutomation/Software%20Testing%20Manual%20vs%20Automated.html

[19] http://andrei.clubcisco.ro/cursuri/anul-2.html

[20]Adrian Iftene – Laborator 3 – Ingineria programarii

[21]http://en.wikipedia.org/wiki/Unit_testing

[22http://junit.org/faq.html

[23]http://en.wikipedia.org/wiki/XUnit

[24]https://maven.apache.org/index.html

[25]http://en.wikipedia.org/wiki/QUnit

[26]http://qunitjs.com/cookbook/

[27] http://www.pmcommunity.ro/2012/03/ce-este-un-tool-de-test-management/

[28] http://www.biblioteca-digitala.ase.ro/biblioteca/pagina2.asp?id=cap4

[29] http://www.todaysoftmag.ro/article/377/din-uneltele-artizanului-software-unit-testing

Anexa 1 – Diagrama Gantt a proiectului

Anexa 2 – Clasificarea costurilor proiectului

Anexa 3 – Clasificarea orelor alocate proiectului

Anexa 4 – Testele și cazurile de test realizate cu JUnit

Similar Posts

  • Recunoasterea Actelor de Vorbire Dintr Un Dialog

    Recunoasterea actelor de vorbire dintr-un dialog Capitolul 1. Introducere Limbajul natural este un fenomen extrem de complicat. El se dezvolta incet si treptat de-a lungul unei perioade indelungate de timp, aparent pentru a optimiza comunicarea dintre oameni. In limbajul natural, apare o mare incidenta a variatiei si incertitudinii. Cea mai mare sursa a variatiei este…

  • Portal Băile Felix

    Cuprins 1.Introducere…………………………………………………………………………………..4 2. Fundamentare teoretica……………………………………………………………………..6 2.1 Baze de date .……………………………………………………………………………7 2.1.1 Tipuri de date în MySQL…………………………………………………………7 2.1.2 Crearea unei tabele în baza de date……………………………………………….7 2.1.3 Inserarea datelor în baza de date………………………………………………….7 2.1.4 Modificarea tabelelor……………………………………………………………..8 2.1.5 Ștergerea de înregistrări din baza de date…………………………………………8 2.1.7 Ștergerea unei baze de date……………………………………………………….8 2.2 Aplicatii web……………………………………………………………………………8 3. Tehnologii utilizate…………………………………………………………………………11 3.1…

  • Verificarea Vorbitorilor Folosind Retea Neurala de Tip Kohonen

    VERIFICAREA VORBITORILOR FOLOSIND O RETEA NEURALA DE TIP KOHONEN 1. INTRODUCERE Prezentare generala In zilele noastre prelucrarea semnalului vocal se regaseste in tot mai multe domenii de activitate cum ar fi: transmisiuni (pe canale telefonice, canale radio), inregistrari sonore, medicina (patologia laringelui), lingvistica (studierea limbilor straine) si nu in cele din urma in recunoasterea automata…

  • Aplicatie Web Pentru Oportunitati de Angajare Si Recrutare

    CUPRINS INTRODUCERE ÎN APLICAȚIILE WEB O aplicație web este o colecție de pagini interconectate, care are scopul de a oferi utilizatorilor o anumită funcționalitate. Aceasta rulează într-un browser web care interpretează codul limbajului de programare utilizat și suportat . Aplicațiile web sunt foarte populare deoarece implică prezența browser-elor web, care sunt omniprezente, dar și datorită…

  • Sistemul Informational Baza de Date a Tezelor de Doctorat

    TEZA DE LICENȚĂ Sistemul Informațional „Baza de date a tezelor de doctorat” CUPRINS ADNOTARE LISTA ABREVIERELOR ÎNTRODUCERE ANALIZA TEHNOLOGIILOR DE CREARE SISTEMUL INFORMAȚIONAL BAREI DE DATE A TEZELOR DE DOCTORAT Analiza sistemului informațional baza de date a tezelor de doctorat existent Selectarea sistemului de gestiune a bazei de date Concluzii la capitolul 1 PROECTAREA ȘI…