Sunteți pe pagina 1din 48

Testarea Unitară

Testarea este necesară și pentru programele scrise într-un limbaj “static” (pentru care se fac
verificări de corectitudine la compilare), dar cu atât mai mult pentru programe scrise într-un limbaj
dinamic și care nu beneficiază de verificările efectuate de un compilator.
În cursul dezvoltării unei aplicații, codul evoluează (fie datorită modificării cerințelor, fie prin
reproiectare sau prin refactorizare), dar prin teste ne putem asigura că acest cod modificat continuă să
respecte cerințele impuse (că este corect).

De ce Unit Testing?
1.Ajută dezvoltatorii să înțeleagă baza de cod și le permite să facă modificări rapide.

2.Testele unitare bune servesc drept documentație a proiectului.

3.Testele unitare ajută la reutilizarea codului. Reutilizând atât codul, cât și testele către un nou proiect.
Modificând codul până când testele rulează din nou.

4.Testele unitare ajută la remedierea erorilor la începutul ciclului de dezvoltare și la reducerea


costurilor.

Menționând aceste aspecte putem indica ce implică testarea unitară Figura 1:


 Teste unitare, care verifică fiecare unitate de program separat de celelalte (o unitate
poate fi o metodă, o clasă, o secvență de apeluri de metode).
o Teste de integrare, care verifică interacțiunile dintre unitățile de program (testate
separat).
o Teste de sistem, care verifică toata aplicația.
o Teste de acceptare, care verifică modul cum programul răspunde cerințelor
beneficiarilor
Fig. 1. Este indicat ce implică testarea unitară

Scrierea de teste unitare, înainte de scrierea codului efectiv, încurajează coeziunea și un cuplaj
slab, în sensul că vom prefera pentru testare să definim clase și metode mai mici (care un singur rol în
aplicație) și cu mai puține dependențe între ele, astfel ca să poată fi testate izolat fiecare.
Cuplajul unei unități de cod poate fi de două feluri:
- Unitatea testată depinde de alte unități
- Alte unități de cod depind de unitatea testată
Este posibil ca unitatea de care depinde secvența testată (o resursă) să nu fie încă disponibilă, să
fie costisitor de utilizat sau să fie impredictibil în comportare. În aceste cazuri se folosesc obiecte
surogat de tip "stub" sau "mock" în locul unui "colaborator" din aplicația reală.
Obiectul surogat poate corespunde unui singur obiect din aplicația finală, unei componente,
unui nivel sau unui subsistem din aplicație.
Un obiect "stub" mimează parțial comportarea unui obiect real (indisponibil), prin transmiterea
unui răspuns corespunzător la fiecare cerere primită (printr-un apel de metodă), fără a ține seama de
succesiunea acestor cereri.
Un obiect "mock" mimează mai bine comportarea obiectului real, pentru că ține cont de
secvența apelurilor și de numărul lor, deci simulează întreaga interacțiune cu obiectul testat.
Testarea unitară în Java este facilitată de existenta mai multe produse software de tip “Test
Framework” dintre care mai folosite sunt JUnit, EasyMock, s.a.
În plus, cele mai importante IDE-uri (Eclipse, NetBeans, IDEA) facilitează efectuarea de teste
prin crearea unui subdirector pentru metodele de test, printr-o comandă (opțiune) de testare aplicație
(alta decât comanda “Run” pentru execuția aplicației) și prin afișarea în mod grafic a rezultatelor
testelor. Atunci când testele eșuează, nu se afișează toată secvența de apeluri de metode care a condus
la eroare “AssertionError” (așa cum se întâmplă în linia de comandă sau când se folosește un IDE mai
simplu care nu are regim special pentru testare unitară).
Elementele de testare unitară, pun la dispoziție unelte pentru a înregistra și repeta teste, pentru
ca testele unitare sa poată fi repetate ușor mai târziu (de regulă când se schimbă o parte din sistem)
astfel încât dezvoltatorul să fie convins ca noile modificări nu au stricat vechea funcționalitate. Acest
lucru mai este cunoscut ca testare regresivă.
Conceptele testării unitare și testării regresive sunt destul de vechi, dar popularitatea lor a
crescut brusc de curând, după apariția unei unelte de testare unitară pentru Java: JUnit.
Testarea unitară se referă la scrierea unor bucăți de cod, denumite cod de testare, care validează
codul de producție. Testarea majorității aplicațiilor devin așadar automată.

Platforme de testare

● C++
- CPPUnit
- Boost.Testing library
- CxxUnit
● Java
- JUnit
- TestNG
● .NET (C#, VB.NET, etc.)
- NUnit

Teste unitare

● Fiecare test unitar (unit test) implementează un singur caz de testare;


● Unitățile sunt testate independent unele fata de altele;
● Pentru fiecare unitate se scriu, în mod uzual, mai multe teste unitare.

Testele unitare au câteva caracteristici importante:

 fiecare test validează un comportament din aplicație;



 rulează foarte repede, maxim în câteva minute;

 sunt foarte scurte și ușor de citit;

 rulează la apăsarea unui buton, fără configurări suplimentare.

Pentru a fi rapide, testele unitare folosesc adesea așa-numitele "duble de testare". La fel cum
piloții de avioane învață într-un simulator înainte de a se urca în avion, testele unitare folosesc bucăți
de cod care seamănă cu codul de producție, dar în realitate folosesc doar la teste. Stub-urile și mock-
urile sunt cele mai întâlnite duble de testare, existând multe altele mai puțin folosite.
Un stub este o dublă de testare care întoarce valori. Stub-ul este similar cu o simulare foarte
simplă: atunci când apeși un buton, apare o valoare.
Un mock este o dublă de testare care validează colaborarea între clase. Mock-ul validează
apeluri de metode, cu anumiți parametri, de un anumit număr de ori. Din această cauză, un mock poate
fi folosit și la validarea apelurilor de metode care nu întorc valori.
Majoritatea unităților de program supuse testelor depind de alți “colaboratori” care pot fi unități
locale (alte metode din aceeași clasă), pot fi parametri ai metodelor testate sau pot fi chiar metode
aflate în alt calculator. Pentru a testa unități cu dependențe de alte unități trebuie înlocuiți colaboratorii
cu obiecte surogat (“stub” sau “mock”). Obiectele surogat se folosesc în testele unitare si vor fi
înlocuite cu obiecte reale în testele de integrare.
Crearea de obiecte surogat în Java se poate face în două feluri:
- Manual, prin scrierea metodelor clasei surogat;
- Automat (dinamic) utilizând un “framework” ca EasyMock, JMock, ș.a.

Clasa surogat scrisă manual trebuie să aibă aceleași metode cu clasa pe care o înlocuiește; acest
lucru se poate face prin extinderea clasei colaborator și redefinirea metodelor sau prin implementarea
unei interfețe definite în scopul testării.
In Java, pentru a facilita trecerea de la teste unitare la teste de integrare se folosesc fie interfețe
(pentru comunicarea cu obiectele surogat), fie obiecte de tip proxy, care interceptează cererile și le
dirijeaz ă fie către obiecte surogat, fie către obiecte reale.
Schema următoare arată o interfață între codul testat și codul de care depinde sau codul surogat
(care înlocuiește în teste codul real).

Fig. 2. Utilizare EasyMock în Java

EasyMock este un framework de testare pentru aplicații Java care generează dinamic clase si
obiecte surogat si poate verifica ordinea apelurilor metodelor din obiectul surogat.
Dublele de testare pot fi create și folosind framework-uri speciale, cum ar fi mockito pentru
Java (a fost portat și pe alte limbaje) sau moc pentru .NET.
Inițial dublele de testare erau folosite doar în locurile unde era foarte greu să controlezi sistemul
sau unde testele erau încetinite de apeluri la sisteme externe. În timp, dublele de testare au ajuns să fie
folosite în toate testele unitare, dând naștere metodei "mockiste" de testare unitară.
Testele unitare sunt scrise de programator, în timp ce implementează o funcționalitate. Din
păcate, cel mai întâlnit mod de a scrie teste este cândva după ce a fost terminată implementarea.
Rezultatul este că testele sunt scrise având în minte cum ar trebui să funcționeze codul și nu testarea
lui.
Test „First Programming” este o metodă de a scrie teste care implică următorii pași:
 crearea unui design pentru implementarea funcţionalităţii;

 crearea minimului de cod necesar (compilabil, dacă limbajul folosit este

 compilat) pe baza design-ului;


 scrierea unuia sau mai multor teste care codează ceea ce trebuie să facă design-

ul; testele vor pica în acest moment;


 implementarea codului care face testele să treacă.

Prin aplicarea testului „First Programming”, programatorii se asigură că scriu teste unitare și că
testează ceea ce ar trebui să rezolve, nu implementarea soluției.

Durează mai mult când scriu teste!

Studiile de caz și experiența personală a programatorilor a arătat că într-adevăr, timpul petrecut


strict pe dezvoltarea unei funcționalități crește odată cu adoptarea testării unitare. Aceleași studii au
arătat că timpul petrecut pe mentenanță scade rapid, arătând ca unit testing poate aduce o îmbunătățire
netă în timpul de dezvoltare.
Acest fapt nu poate schimba percepția programatorului care trebuie să scrie mai mult cod. De
aceea, programatorii presupun adesea că per total proiectul derulează mai încet din cauza testării
automate.
Este bine ca „adopția” unit testing să se facă cu grijă, incremental, urmărind câteva puncte
importante:
 Clarificarea conceptelor legate de unit testing înainte de a începe scrierea de

teste.
Programatorii trebuie să poată "mânui" fără teamă unelte precum: stub-uri, mock-uri,
teste de stare, teste de colaborare, teste de contract. De asemenea, programatorii trebuie să
înțeleagă ce cazuri merită și trebuie testate.
Greșeli comune

Câteva greșeli comune legate de unit testing sunt:


 Scrierea multor teste de integrare(care implică mai multe clase sau module) lente

 și fragile în detrimentul testelor unitare mici, rapide și ușor de întreținut


 Abandonarea dublelor de testare, sau folosirea lor în scopuri pentru care nu au

 fost create. Dublele de testare ajută la obținerea unor teste scurte și rapide.
 Numele testelor nu exprimă comportamentul testat. Numele testului poate da

foarte multe informații atunci când testul pică.


 Folosirea intensivă a debugger-ului pe teste. Testele bine scrise vor spune
imediat unde este problema în cazul în care pică. Debugging-ul este în continuare util în situații

exotice.
 Cod de testare neîngrijit. Codul de testare este cel puțin la fel de important ca și
codul de producție, și trebuie întreținut cu aceeași grijă.

Un programator utilizează în general un cadru UnitTest pentru a dezvolta cazuri de testare


automate. Folosind un cadru de automatizare, dezvoltatorul codifică criteriile în test pentru a verifica
corectitudinea codului. În timpul executării cazurilor de test, cadrul înregistrează cazurile de test
nereușite. Multe cadre vor semnaliza și raporta automat, pe scurt, aceste cazuri de test nereușite. În
funcție de gravitatea unui eșec, cadrul poate opri testarea ulterioară.
Fluxul de lucru al testării unitare este
1) Crearea cazurilor de testare
2) Revizuirea / reelaborarea

Avantajul testarii unitare:

Dezvoltatorii care doresc să afle ce funcționalitate oferă o unitate și cum să o folosească pot
examina testele unitare pentru a obține o înțelegere de bază a API-ului unității.

 Testarea unității permite programatorului să refactorizeze codul la o dată ulterioară și să


se asigure că modulul funcționează în continuare corect (adică testarea de regresie).
Procedura constă în scrierea cazurilor de test pentru toate funcțiile și metodele, astfel
încât ori de câte ori o modificare provoacă o eroare, aceasta poate fi identificată și
remediată rapid.

 Datorită naturii modulare a testării unitare, putem testa părți ale proiectului fără a
aștepta finalizarea altora.
Dezavantaje
Nu se poate aștepta ca testarea unității să surprindă fiecare eroare dintr-un program. Nu este posibil să
se evalueze toate căile de execuție chiar și în cele mai banale programe.

 Testarea unitară prin natura sa se concentrează pe o unitate de cod. Prin urmare, nu poate
detecta erori de integrare sau erori la nivel de sistem.

Se recomandă utilizarea testelor unitare împreună cu alte activități de testare.

TESTARE UNITARA în Java


Termenul de 'testare unitara' se refera la testarea individuala a unor unitati separate dintr-un sistem
software. In sistemele orientate spre obiecte, aceste 'unitati' sunt de regula clase si metode.

Elementele de testare unitara va pun la dispozitie unelte pentru a inregistra si repeta teste, pentru

ca testele unitare sa poata fi repetate usor mai tarziu (de regula cand se schimba o parte din sistem), astfel
incat dezvoltatorul sa fie convins ca noile modificari nu au stricat vechea functionalitate. Acest lucru e
cunoscut ca testare regresiva.

Conceptele testarii unitare si testarii regresive sunt destul de vechi, dar popularitatea lor a crescut brusc
de curand, dupa publicarea metodologiei de programare eXtreme si dupa aparitia unei unelte de testare
unitara pentru Java: JUnit.

Dezvoltarea bazată pe teste (TDD=Test Driven Development) este metodologia în care testele unitare se
scriu înainte de a scrie codul unitătilor testate. Scrierea timpurie a testelor este o activitate de proiectare ,
deoarece necesită întelegerea cerintelor si poate conduce la refactorizrea codului. TDD impune gândirea
codului în functie de intentiile lui si nu în functie de implementare.

Scrierea de teste unitare, înainte de scrierea codului efectiv, încurajează coeziunea si un cuplaj slab, în
sensul că vom prefera pentru testare să definim clase si metode mai mici (care un singur rol în aplicatie) si
cu mai putine dependente între ele, astfel ca să poată fi testate izolat fiecare.

Cuplajul unei unităti de cod poate fi de două feluri:


- Unitatea testată depinde de alte unităti
- Alte unităti de cod depind de unitatea testată
In plus, cele mai importante IDE-uri (Eclipse, NetBeans, IDEA) facilitează efectuarea de teste prin crearea
unui subdirector pentru metodele de test, printr-o comandă (optiune) de testare aplicatie (alta decât comanda
“Run” pentru executia aplicatiei) si prin afisarea în mod grafic a rezultatelor testelor. Atunci când testele
esuează (“fails”) nu se afisează toată secventa de apeluri de metode care a condus la eroare “AssertionError”
(asa cum se întâmplă în linie de comandă sau când se foloseste un IDE mai simplu care nu are regim special
pentru testare unitară).

Testarea programelor Java cu JUnit

Testarea unitara s-a impus in ultima perioada in dezvoltarea proiectelor scrise in limbajul Java ,pe masura
aparitiei unor utilitare gratuite de testare a claselor, care au contribuit la cresterea vitezei de programare si la
micsorarea drastica a numarului de bug-uri.

Cel mai folosit utilitar pentru testarea unitara a claselor Java este JUnit, mai este si TestNG, care se poate
descarca gratuit de pe site-ul http://www.junit.org . Arhiva este destul de mica si include un director
(junitxxx) cu documentatie (in directorul doc), documentatia API (in directorul javadoc), biblioteca de clase
junit.jar si exemple de clase de test (in directorul junit).

Metodele setUp() si tearDown() servesc la initializarea si distrugerea oricarui obiect utilizat in cadrul
testelor. Fiecare test ruleaza intr-un context propriu si apeleaza metoda setUp() inainte si metoda
tearDown()dupa fiecare metoda de test pentru a evita efectele secundare dintre teste.
Instantele TestCase se pot compune sub forma unor ierarhii TestSuite ce vor invoca automat toate metodele
test123() definite in fiecare instanta TestCase. O clasa TestSuite poate fi compusa din alte teste, instante
TestCase sau alte instante TestSuite.

Diagrama de clase a pachetului junit.framework este urmatoarea:

Testarea unitară verifică, pentru fiecare unitate de program, faptul că, pentru anumite date initiale,
rezultatele sunt cele asteptate. In acest scop se scrie pentru fiecare metodă testată o functie de test în care se
folosesc asertiuni.

In functiile de test se folosesc în general obiecte ale clasei testate; aceste obiecte pot fi create în interiorul
metodei sau în afara metodelor de test. In acest scop sunt prevăzute în clasa de test metodele cu numele
“setUp” si “tearDown” (JUnit 3) sau metode cu orice nume dar adnotate cu @Before si @After. Metoda
“setUp” creează obiectele necesare metodelor de test si initializează variabile ale clasei care vor fi folosite în
metodele de test, înainte de fiecare test. Metoda pereche “tearDown” anulează operatiile din “setUp” si reface
starea initială, dacă e necesar.

Mai multe clase de test formează o suită de teste (“TestSuite”) care se execută automat, în câteva moduri
posibile:

- din linia de comandă cu rezultate afisate în mod text:


java org.junit.runner.JUnitCore TestClass1 [...other test classes...]

- dintr-un program Java, cu rezultate afisate în mod text:


org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);

- dintr-un IDE, cu rezultate în mod grafic.


JUnit execută succesiv toate metodele de test, memorează exceptiile produse si le afisează la final. De
remarcat că prin apelarea metodelor testate pot să apară si alte exceptii datorate unor conditii neprevăzute si
care pot întrerupe secventa de teste (ele nu ar trebui să apară în practică).

Clasa “TestCase” extinde, la rândul ei, clasa “Assert” de la care preia mai multe metode de tip “assert” cu
rolul de a verifica îndeplinirea anumitor conditii.

JUnit annotations

Annotation Description

@Test The @Test annotation identifies a method as a test method.


public void method()

2
Annotation Description

@Test (expected = Fails if the method does not throw the named exception.
Exception.class) Eșuează dacă metoda durează mai mult de 100 de milisecunde.
@Test(timeout = 500)
public void testTimeout() {
@Test(timeout=100)
System.out.println("@Test(timeout) can be used to enforce timeout in JUnit4 test case");
while (1 == 1) {

}
}

Această metodă este efectuată înainte de fiecare test. Acesta este utilizat pentru a pregăti mediul de testare (de exemplu, citi date de intrare, inițializa clasei).
@Before
@Before
public void method()
public void setUp() {
System.out.println("@Before method will execute before every JUnit4 test");
}

Aceasta metoda este executată după fiecare test. Este folosit pentru a curăța mediul de testare (de exemplu, de a șterge datele temporare, a restabili valorile implicite). Se poate salva, de asemenea, memorie de curățare structuri de
memorie scumpe.

@After @After
public void method() public void tearDown() {
System.out.println("@After method will execute after every JUnit4 test");
}

Această metodă se execută o dată, înainte de începerea toate testele. Acesta este utilizat pentru a efectua activități intensive de timp, de exemplu,
@BeforeClass să se conecteze la o bază de date.metoda trebuie sa fie marcata cu modificatorul static.
public static void
method() Această metodă este executat o data, dupa ce toate testele au fost finalizate. Acesta este utilizat pentru a efectua activități de curățare, de
exemplu, să se deconecteze de la o bază de date. metoda trebuie sa fie marcata cu modificatorul static.

@AfterClass
public static void
method()

@Ignore Ignoră metoda de testare. Acest lucru este util atunci când codul care stau la baza a fost schimbat, iar
cazul de testare nu a fost încă adaptată. Sau, în cazul în care timpul de executie a acestui test este
prea lung pentru a fi incluse.
@Ignore("Not yet implemented")
@Test
public void testGetAmount() {
System.out.println("getAmount");
fail("@Ignore method will not run by JUnit4");
}

Test methods
Statement Description

3
Statement Description

Lasă metoda sa eșuează. S-ar putea fi folosite pentru a verifica dacă o anumită parte a codului nu este atins sau de a avea un test de faptul că nu înainte de codul de test este pus în aplicare. Parametrul
fail(String) String este opțional

Checks that the boolean condition is true.

assertTrue([message], boolean
condition)
Checks that the boolean condition is false.

assertFalse([message],
boolean condition)
Testează că două valori sunt aceleași. Notă: pentru tablouri nu este verificat de referință a conținutului de tablouri.

assertEquals([String
Test that float or double values match. The tolerance is the number of decimals
message], expected, actual)
which must be the same.

assertEquals([String message],
Checks that the object is null.
expected, actual, tolerance)

Checks that the object is not null.


assertNull([message], object)

Checks that both variables refer to the same object.


assertNotNull([message], object)

assertSame([String], expected,
Checks that both variables refer to different objects.
actual)

assertNotSame([String],
expected, actual)

Fiecare metodă de tip “assert” poate avea un parametru suplimentar de tip “String” care este un mesaj
afisat în caz că asertiunea (conditia) este falsă, dar întotdeauna o metodă “assert” generează o exceptie în
caz de asertiune falsă (“AssertionFailedError”).

Teste unitare efectuate pot fi clasificate în trei categorii:


● teste pozitive : se verifică rezultatul asteptat al unei actiuni
● teste negative: se verifică comportarea în cazul unor date de intrare incorecte (parametri de ex.)
● teste de producere exceptii: se verifică dacă sunt tratate exceptiile posibile

public class MyUnit {


public String concatenate(String one, String two){
return one + two;
}

4
}
import org.junit.Test;
import static org.junit.Assert.*;
public class MyUnitTest {
@Test
public void testConcatenate() {
MyUnit myUnit = new MyUnit();
String result = myUnit.concatenate("one", "two");
assertEquals("onetwo", result);
}
}

Dezvoltare prin teste


Cuprins:
- Definitie;
- Ciclul dezvoltarii prin testare;
- Avantaje;
- Dezavantaje;
Definitie:
- TDD este una din cea mai
bună metodă cunoscută
de a face design
incremental. Practicienii
TDD codifică exemplele
folosind teste care sunt
apoi păstrate pentru a
valida soluția completă.
Prin identificarea și
diminuarea similarităților
din cod în pasul de
refactorizare, design-ul
este simplificat și
îmbunătățit în continuu.
Ciclul dezvoltarii prin testare:
Dezvoltarea prin testare presupune citeva etape:
● Adaugare test;
● Rularea tuturor testelor(testele noi sa
nu treaca);
● Scrierea codului;
● Rularea tuturor testelor(testele noi sa treaca);
● Refactorizarea codului;
● Repetarea ciclului;
Adaugare test:
În dezvoltarea prin testare, adăugarea unei noi
funcționalităţi începe cu scrierea testului. Inevitabil,
acest test nu va trece, deoarece codul
corespunzător nu este încă scris. (În cazul în care
testul scris a trecut, înseamnă că "noua"
funcționalitate există deja, sau testul este greșit.)
Pentru a scrie testul, dezvoltatorul trebuie să fi
înțeles în mod clar care cerinţe trebuie îndeplinite
de noile functionalitati. Se iau în considerare noile
cazuril de utilizare. Noile cerințe pot aduce, de
asemenea, la modificări ale testelor existente.
Rularea tuturor testelor (testele noi sa
nu treaca):
● În acest stadiu, se verifică că testele
scrise nu trec. Această etapă verifică, de
asemenea testele: testele scrise pot trece
în orice moment și, în consecință, să fie
inutil. Noi teste nu ar trebui să treaca la
motive lesne de înțeles. Acest lucru va
spori încrederea (deși nu există nici o
garanție în întregime), care test este
într-adevăr de testare pentru care a fost
dezvoltat.
Scrierea codului:
- În această etapă se adaugă codul astfel ca
testul va trece. Acest cod nu trebuie să
fie perfect. Trebuie sa fie acceptabil, asa
ca treaca testul într-un fel. Pentru că pașii
următori vor îmbunătăți și lustrui codul.

- Este important să se scrie cod care va face


sa treacă testul. Nu adăugați funcționalitati
inutile și care nu a fost testate.
Rularea tuturor testelor
(testele noi sa treaca): Refactorizarea codului:

Dacă toate testele trec, Când a ajuns la


programatorul poate fi funcționalitatea necesară,
sigur că codul acest cod poate fi curățat.
îndeplinește toate Refactorizare - procesul
cerințele de testare. de schimbare a structurii
Puteți trece apoi la etapa interne a programului, nu
finală a ciclului. afectează
comportamentul său
extern. Are scopul de a
facilita înțelegerea
funcționării softului,
pentru a elimina dublarea
de cod, pentru a facilita
schimbări în viitorul
apropiat.
Exemplu:
Exemplu:
@Test
public final void
whenSemicolonDelimiterIsSpecifiedThenItIsUsedToSeparateNumbers() {
Assert.assertEquals(3+6+15, StringCalculator.add("//;n3;6;15"));
}
@Test
public final void whenOneNumberIsUsedThenReturnValueIsThatSameNumber()
{ Assert.assertEquals(3, StringCalculator.add("3"));
}

@Test
public final void whenTwoNumbersAreUsedThenReturnValueIsTheirSum()
{ Assert.assertEquals(3+6, StringCalculator.add("3,6"));
}
Exemplu:
@Test
public final void
whenNegativeNumbersAreUsedThenRuntimeExceptionIsThrown() {
RuntimeException exception = null;
try {
StringCalculator.add("3,-6,15,-
18,46,33"); } catch (RuntimeException e) {
exception = e;
}
Assert.assertNotNull("Exception was not thrown", exception);
Assert.assertEquals("Negatives not allowed: [-6, -
18]", exception.getMessage());
}
Exemplu:
@Test
public final void whenAddIsUsedThenItWorks() {
Assert.assertEquals(0, StringCalculator.add(""));
Assert.assertEquals(3, StringCalculator.add("3"));
Assert.assertEquals(3+6, StringCalculator.add("3,6"));
Assert.assertEquals(3+6+15+18+46+33,
StringCalculator.add("3,6,15,18,46,33"));
Assert.assertEquals(3+6+15, StringCalculator.add("3,6n15"));
Assert.assertEquals(3+6+15, StringCalculator.add("//;n3;6;15"));
Assert.assertEquals(3+1000+6,
StringCalculator.add("3,1000,1001,6,1234"));
}
Avantaje:
Testele pot fi salvate ca documentatie;
Este mai usor de realizat refactorizarea;
Ajuta la evitarea erorilor;
Programatorii care scriu teste sunt
mai productivi;
Se reduce timpul efectiv;
Dezavantaje:
Exista probleme care nu pot fi
rezolvate prin testare(
securitate);
Complicat de implementat cind
este nevoie sa treaca testele
functionale (implemetarea
interfetei, aplicatii cu BD);
Multimea de teste poate provoca
prea multa incredere, ceea ce
cauzeaza un control mai slab.
Introducere în testarea automată

Lucrând cu o infrastructura software şi hardware din ce în ce mai complexă, confruntaţi cu


creşterea continuă a cerinţelor de calitate şi cu necesitatea reducerii costurilor, firmele de software
sunt nevoite să preţuiască tot mai mult soluţii solide, inginereşti, de dezvoltare a produselor
software.
Testarea produsului este în software o componentă majoră în procesul de dezvoltare. Firmele
din industria tradiţională – de ex. industria de maşini, de construcţii, de produse electronice sau
alimentare au de zeci de ani departamente de testare şi verificare a calităţii. În materie de software,
organizarea şi automatizarea muncii de testare şi verificare a produselor a început din motive
istorice evidente abia în anii '80.
Testarea manuală, mult timp văzută ca singura soluţie de a descoperi eventualele defecte,
întârzie foarte mult lansarea pe piaţă a produsului şi induce cheltuieli semnificative mai ales în
cazul descoperirii efectelor laterale – atât în procesul dezvoltării unei aplicaţii cât şi în cazul
schimbărilor ulterioare.
Totodată procedurile de testare manuală, prin natura lor limitată, nu reuşesc să descopere
toate defectele şi nu au nici o şansă să simuleze condiţii de utilizare simultană, intensivă, a unei
aplicaţii. Există numeroase căi de a îmbunătăţi procesul de testare, una dintre cele mai eficiente
fiind testarea automată. Testele automate execută o secvenţă de acţiuni fără intervenţie umană şi
pot simula utilizarea unei aplicaţii simultan. În general, majoritatea produselor necesită să fie testate
de mai multe ori, pe mai multe platforme software şi hardware, ca şi după schimbările ulterioare
sau la lansarea unei noi versiuni de produs. Prin folosirea testării automate, costurile testărilor
repetate se reduc aproape la zero.
Cele mai importante beneficii sunt:
- acoperirea tuturor etapelor de testare de la concepţie până la lansare
- posibilitatea simulării testării cu mai mulţi utilizatori
- posibilitatea repetării testelor
- creşterea siguranţei în produs.
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
De aceea una din calităţile care trebuie să le aibă un astfel de sistem este posibilitatea 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
scenarii : 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 erorilor descoperite în urma testării. Un sistem de test evoluat sprijină utilizatorii
printr-un sistem de documentare pe tot parcursul acestui proces.
Într-o abordare mai detaliată testarea automată înseamnă:
● planificare
- identificarea cerinţelor şi a funcţionalităţilor
- gruparea acestora în condiţii de test
- crearea cazurilor de test pentru aceste condiţii
- design
construcţia scripturilor de test
generarea testelor de rulare
execuţie
crearea scenariului de rulare a scripturilor
rularea uneltelor monitor pentru înregistrarea datelor
înregistrarea rezultatelor pentru fiecare rulare
raportarea şi gestionarea erorilor
management
generarea rapoartelor şi graficelor
controlul dintr-un singur punct de comandă
documentarea permanentă a stadiului curent al proiectului

Tipuri de testare automată :

structurală (white-box testing) - se verifică structura software-ului şi necesită


acces complet la codul sursă. Acest tip de testare verifică dacă structura codului este eficientă: bucle
complicate, zone de date comune, mii de linii de cod încurcate sunt numai câteva din problemele
care pot fi îndepărtate. Scopul acestui test este mărirea performanţei aplicaţiei şi a lizibilităţ ii
codului.
funcţională (black-box testing) – se definesc aşteptările clientului de la
aplicaţie şi se verifică automat dacă software-ul se comportă conform acestor aşteptări. Prin testele
ce se execută se observă comportamentul aplicaţiei, evidenţiat prin datele de ieşire, fără a se face
referire la funcţiile interne.
regresivă (regression testing) - se verifică dacă s-a modificat neaşteptat
comportamentul aplicaţiei în urma implementării unor noi cerinţe/schimbări.
negativă (negative testing) - se solicită aplicaţia, producând deliberat cazuri
complicate, neobişnuite sau particulare pentru a forţa apariţia erorilor.
de solicitare (stress testing) - se determină capabilităţile absolute ale aplicaţiei
şi ale infrastructurii pe care este implementată; cu ajutorul acestui tip de test se dezvăluie
caracteristicile de performanţă ale unui sistem menţinut în condiţii de încărcare totale, adică sunt
pornite şi rulate toate serviciile care în mod normal ar fi fost rulate separat în timp şi independent.
de performanţă (performance testing) - în urma acestui tip de testare se
verifică dacă performanţa aplicaţiei este adecvată pentru cerinţele stabilite, în termeni de viteză de
acces, resurse de sistem utilizate şi procesarea cererilor de acces.
de încărcare (load testing) - se determină punctele slabe ale aplicaţiei şi dacă
sunt necesare îmbunătăţiri ale infrastructurii hardware sau software prin măsurarea caracteristicilor
de performanţă şi scalabilitate a principalelor componente ale aplicaţiei web; de regulă aceasta se
realizează prin creşterea numărului de sesiuni utilizator sau a conexiunilor TCP/IP.

Limitele testării automate

Sunt multe lucruri pe care uneltele de testare automată nu le pot face şi este important să se
cunoască aceste limitări pentru a alege calea 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 decât
în măsura în care au fost definite complet cerinţele aplicaţiei respective. Unele teste, mai ales
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 computer. 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.
Tipuri de unelte pentru testarea automată

Sistemele de testare automată pot include unelte de genul :


GUI , prin folosirea metodei "înregistrare/redare"
analizoare de cod - analizează complexitatea codului scris, respectarea unor standarde
de scriere a codului
analizoare de memorie - detectează depăşirea memoriei alocate, suprascrieri în zone
nealocate şi zone rămase nealocate
testare de solicitare/performanţă - pentru testarea aplicaţiilor web şi client/server în
diferite scenarii de solicitare
testare servere web - verifică validitatea şi integritatea link-urilor, a codului html,
programe client-side şi server-side, securitatea transmiterii datelor
alte unelte - pentru managementul documentaţiei, raportării erorilor,
configuraţiei, etc.

Comparaţie între testarea manuală şi automată

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 scoate în
evidență erorile.
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 erorilor ş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.
alternativă interesantă este aşa-numita "testare parţială". Această soluţie este combinaţie
de jumătate testare manuală şi jumătate testare automată, aceasta din urmă fiind folosită numai acolo
unde se pot obţine beneficii maxime.
Testarea automată se doreşte a fi soluţia ideală pentru reducerea timpului de dezvoltare şi a
costurilor. O echipă de testeri poate să pornească uneltele de testare automată, să le lase să ruleze şi
în final să colecteze şi să analizeze rezultatele. Timpul este astfel mai bine organizat şi poate fi
petrecut pentru izolarea şi raportarea erorilor.
În zilele noastre sunt multe unelte pe piaţă care pot ajuta la planificarea, execuţia şi crearea de
rapoarte în activitatea de testare. Majoritatea acestor unelte necesită cunoştinţe de specialitate
pentru a le implementa şi utiliza corespunzător. De asemenea, este bine de ştiut, că suitele
profesionale de unelte specializate în asigurarea calității oferă întotdeauna un produs de sine
stătător care preia partea de management de proiect şi pe cea de raportare a erorilor. Un asemenea
produs este de exemplu TestDirector de la firma Mercury Interactive – market leader în materie de
produse pentru asigurarea calităţii. Acest produs poate fi corelat cu diverse sisteme de control al
versiunii folosite în implementare şi poate fi configurat în aşa fel, încât rapoartele automate create
de uneltele de testare şi/sau monitorizare a aplicaţiilor să fie preluate automat în sistemul, astfel
încât citirea şi interpretarea manuală a rapoartelor de testare nu mai este necesară. Erorile sunt
parcurse și analizate de către TestDirector, care generează pe baza rapoartelor de testare email-uri,
sms sau alte modalităţi de atenţionare a echipei de implementare.
Este necesar de menţionat că un sistem ca TestDirector poate fi folosit pentru partea de
management a proiectului şi în combinaţie cu testarea manuală, caz în care informaţiile despre ceea
ce trebuie testat se formalizează drept scenarii de testare, iar rezultatele testului manual trebuiesc
introduse de către tester manual în sistem.
Soluţiile elegante pentru testarea sistemelor sofisticate sunt adesea limitate numai de
imaginaţia tester-ilor.

Câteva dintre avantajele utilizării testării automate sunt:


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, scenarii)

execuţia automată a testelor de performanţă în fazele de început ale


proiectului poate evita eforturile de re-design în fazele ulterioare
odată ce scenariile de testare automată sunt implementate, o parte din personal poate
fi redirecţionat către alte necesităţi
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 (scenariile de testare pot fi rulate şi după orele
de program economisind astfel timp)
generarea rapidă a condiţiilor de testare
c) avantaje privind calitatea
• o mai bună înţelegere a scopului testării
• o acoperire mai mare a elementelor de testat
• rezultate mai consistente datorită repetabilităţii testelor
• compararea automată a rezultatelor

Procesul testării automate

Majoritatea uneltelor de testare automată sunt compatibile cu entităţile software ce intervin pe


traseul de la clienţi la furnizorul de aplicaţii.
Procesul de testare automată presupune un efort de management deosebit. Acest proces
începe încă din faza de analiză a aplicaţiei şi continuă în toate etapele de dezvoltare. În diagrama
următoare se pot observa etapele procesului, ordinea şi frecvenţa acestora, precum şi locul central
pe care îl ocupă managementul defectelor şi serviciile. Un factor important este menţinerea centrală
a comunicării între etape pentru managementul erorilor.
Fig.1 Procesul de testare automată

Testarea automată nu va putea înlocui în întregime testarea manuală şi nici nu trebuie. Tester-ii
pot să observe cum un utilizator poate interacţiona cu produsul, în timp ce un sistem de testare
automată nu poate întotdeauna să prevadă aceste acţiuni sau să găsească cea mai bună cale de a le
testa. Dacă sunt bine folosite, programele de testare automată măresc considerabil productivitatea
QA, economisesc costuri, măresc semnificativ consistenţa şi calitatea produsului şi ajută la
optimizarea şi accelerarea procesului de dezvoltare al unei aplicaţii. Deja în ţările cu tradiţie în
dezvoltarea de software există cerinţa ca toate produsele software din sectorul militar, medical,
guvernamental şi financiar să fie testate cu unul din sistemele recunoscute de testare automată, iar
rapoartele automate asupra felului cum a decurs testarea constituie baza acceptării unei aplicaţii de
către client.

1 Documente necesare pentru planificare


Plan de testare: un document ce descrie scopul, abordarea, resursele şi programul pentru
activităţile de testare ce se vor desfăşura.
Prezintă strategia ce va fi folosită pentru a verifica şi asigura că un produs sau un sistem
întâlneşte specificaţiile de design şi alte cerinţe.
Pregătit de un inginer de testare identifică funcţionalităţile ce se vor testa, atribuţiile de
testare, cine şi ce va testa, mediul de testare, tehnicile de creare a testelor, tehnicile de măsurare a
testelor, precum şi riscurile ce pot interveni în planificare.
Planul de testare – noţiuni generale:
Un plan de testare poate include una sau mai multe dintre următoarele:
- Verificarea designului – va fi realizată în timpul dezvoltării produsului sau al
stadiului de aprobare, de obicei de către un număr restrâns de persoane.
- Teste de producţie – vor fi realizate în timpul pregătirii sau asamblării produsului
pentru scopurile de verificare a performanţei şi a controlului de calitate.
- Acceptanţa – va fi făcută la momentul primirii sau instalării produsului.
- Teste de întreţinere (support) – vor fi făcute pe toată perioada de viaţă a
produsului, atunci când este nevoie.
- Teste de regresie – vor fi realizate pe un produs existent şi operaţional, pentru a
verifica dacă funcţionalitatea existentă nu a fost stricată atunci când alte aspecte ale mediului se
schimbă.
Formatele documentelor de planificare a testării pot fi la fel de variate ca produsele şi
organizaţiile în care se aplică. Exista trei elemente care ar trebui descrise într-un plan de testare:
acoperirea testelor, metodele de testare, responsabilităţile de testare.
Acoperirea testelor descrie cerinţele care trebuie verificate şi în ce stadii ale ciclului de
producţie. Aceasta derivă din specificaţiile de design şi alte cerinţe, cum ar fi standarde de
siguranţă. Fiecare cerinţă va avea una sau mai multe metode de verificare corespunzătoare.
Metodele de testare arată cum se va executa acoperirea testelor. Deasemenea, acestea
specifică echipamentul de testare care va fi folosit în performanţele testelor, precum şi criteriile de
trecere a unui test.
Responsabilităţile de testare stabilesc echipele/resursele ce vor realiza metodele de
testare şi la ce nivel din viaţa produselor. Astfel organizaţiile pot să stabilească, să achiziţioneze şi
să dezvolte echipamente de testare şi alte resurse necesare pentru a implementa metodele de
testare de care sunt responsabile. Responsabilităţile de testare includ datele ce ar trebui adunate şi
modalităţile de păstrare şi raportare.

Conţinutul unui plan de testare:


Conţinutul unui plan de testare poate varia de la echipă la echipă. Scopul planului de
testare este acela de a stabili lista de paşi care vor fi urmaţi pentru a identifica cerinţele care nu au
fost îndeplinite în software. Există multe standarde care se folosesc pentru a dezvolta un plan de
testare.
IEEE 829-1998, cel mai întâlnit standard pentru planul de testare. Structura unui plan:
● Identificatorul planului de testare
● Introducere
● Aspectele ce vor fi testate
● Aspectele ce nu vor fi testate
● Abordarea
● Criteriul de trecere a testelor
● Rezultatele testelor
● Responsabilităţi
● Nevoi tehnice
● Nevoi de personal şi training
● Program
● Riscuri
● Aprobări
Identificatorul planului de testare specifică identificatorul unic desemnat pentru plan.
Introducere - rezumă caracteristicile produsului ce urmează sa fie testate. Conţine
următoarele informaţii: numele proiectului ce va fi testat, istoria review-urilor, definiţii si
terminologie, numele celor care aproba documentul, referinţe, sumarul planului de testare,
acoperirea testării, identifică elementele de testare, incluzând versiunile lor.
Specifică caracteristicile mediului de transmitere, care impactează cerinţele de hardware.
Oferă referinţe la următoarele elemente, daca ele există: Specificaţiile cerinţelor,
Specificaţiile de design, Manualul de utilizare, Manualul de instalare.

2
Aspecte ce vor fi testate identifică toate caracteristicile produsului şi combinaţii de
caracteristici ce vor fi testate. Identifică specificaţiile de design, asociate cu fiecare caracteristică şi
fiecare combinaţie de caracteristici.
Aspecte ce nu vor fi testate identifică toate caracteristicile şi combinaţiile care nu vor fi
testate, precum şi motivele pentru aceasta.
Abordarea - Specifică abordarea care va asigura testarea adecvată a unui grup de
implementări. Abordarea trebuie descrisă cu suficiente detalii pentru a permite identificarea
activităţilor majore de testare şi estimarea timpului necesar pentru fiecare dintre ele. Identifică
constrângerile semnificative asupra testării, cum ar fi disponibilitatea unui test, a resurselor şi a
termenelor limită, precum şi strategia de automatizare.
Criteriul de trecere - Specifică acel criteriu care va fi folosit pentru a determina dacă
fiecare test a trecut sau a picat.
Criteriul de suspendare - Specifică acele criterii folosite pentru a suspenda o parte sau
toată activitatea de testare a unui item, asociat cu planul de testare. Precizează ce activităţi de
testare trebuie repetate, atunci când se reia procesul de testare.
Activităţile de testare - Identifică un set de activităţi necesare pentru a pregăti și executa
testarea. Identifică toate interdependenţele - între activităţi şi orice cunoştinţe speciale necesare.
Rezultatele testării - Identifică documentele ce vor fi livrate. Următoarele documente ar
trebui incluse:
● planul de testare
● specificaţiile de design ale testului
● specificaţiile cazului de testare
● specificaţiile procedurii de testare
● rapoartele de transmitere a testului
● logourile de testare
● rapoartele incidentelor de testare
● rapoartele sumarelor testelor
● deasemenea, se pot include utilitarele de testare.
Nevoile de training - Specifică nevoile personalului de pregătire, în funcţie de nivelul de
cunoştinţe. Identifică opţiuni de pregătire pentru a obţine nivelul dorit.

3
Nevoi tehnice - Precizează atât proprietăţile necesare, cât şi pe cele dorite ale mediului de
testare. Această specificaţie ar trebui să conţină caracteristicile fizice ale locaţiilor, incluzând
hardware, comunicaţii, software, modul de utilizare, precum şi orice alt software necesar pentru a
susţine un test. Deasemenea, precizează nivelul de securitate ce trebuie asigurat locaţiei,
sistemului software, datelor şi hardware. Identifică utilitare speciale necesare, precum şi orice alte
nevoi implicate în procesul de testare. Responsabilităţi - acestea identifică grupurile responsabile
cu managementul, designul, pregătirea, executarea, verificarea şi rezolvarea specificaţiilor şi
activităţilor legate de procesul de testare. Suplimentar, identifică grupurile responsabile pentru
asigurarea execuţiei testelor şi nevoilor de hardware. Aceste grupuri pot include programatori,
ingineri de testare, reprezentanţii utilizatorilor, suport tehnic, management de produs.
Program - Include datele importante identificate în programul proiectului software,
precum şi toate evenimentele de transmitere către client. Defineşte orice alt termen limită necesar.
Estimează timpul necesar pentru a executa fiecare activitate de testare. Specifică programul pentru
fiecare activitate şi termen limită. Pentru fiecare resursă de testare (de exemplu, locaţie,
instrumente şi personal), trebuie specificată perioada de folosinţă.
Riscuri - Identifică presupunerile cu risc mare ale planului de testare. Specifică planuri de
abordare pentru fiecare risc (de exemplu, livrarea întârziată a unei caracteristici testate poate
necesita program prelungit al personalului).
Aprobări - Specifică numele şi titlurile persoanelor care trebuie să aprobe acest plan de
testare.
Paşii planificării testelor :
- Cercetarea, colectarea şi documentarea strategiei, tacticilor şi activităţilor interne
ale testelor
Calcularea riscurilor, prin enumerarea riscurilor posibile, impact, prioritate.
Negocierea şi documentarea lucrurilor între subproiectul testării şi proiectul general
Finalizarea si documentarea detaliilor de planificare şi logistică, precum definiţiile
termenilor de testare şi de proiect. Notarea oricărui document la care se face referire.
Identificarea unor acţiuni în cazul apariţiilor situaţiilor de risc.
Planificarea testelor: estimarea eforturilor de test, determinarea costurilor,
programul de realizare a atribuţiilor.
Planul este dezvoltat în detaliu.

4
Se definesc atribuţiile fiecarui inginer de testare, strategia de testare, metrici. Se
definesc criteriile de oprire a testării.
Răspândirea planului pentru revizuire privat, de multe ori mai întâi la echipa de
testare, apoi clienţilor sau altor factori de decizie. Adunarea părerilor şi revizuirea planului,
precum şi reluarea primilor paşi, dacă este nevoie. Executarea schimbărilor la programul estimat şi
buget, rezultate în urma procesului de planificare. Răspândirea planului pentru revizuire publică.
Ţinerea unei şedinţe pentru revizuirea cu factorii de decizie. Adunarea ajustărilor finale necesare.
Revizuirea programului estimat şi bugetului bazat pe cunoştinţe noi, obţinute după procesul de
planificare, incluzând folosirea resurselor. Dacă rezultatele presupun modificări peste limitele
alocate, escalarea acestora pentru rezolvare. Reiterarea primilor paşi sau refacerea estimărilor.
Introducerea planului de testare în sistemul bibliotecilor proiectului, precum şi plasarea acestuia
pentru acces la citire, fără modificări.
Controlul procesului de testare
Controlul calităţii implică monitorizarea rezultatelor specifice ale proiectului în vederea
măsurării conformităţii lor cu standardele şi reglementările de calitate şi identificarea căilor de
eliminare a cauzelor de neconformitate. Va identifica şi implementa măsuri de corectare nu doar
pentru procesul de testare, dar şi pentru alte activităţi ale ciclului de viață software. Paşii de bază:

 Observarea şi evaluarea ieşirilor rezultate, comportamentelor şi stărilor.



 Raportarea şi/sau rezolvarea oricăror diferenţe faţă de rezultatele asteptate.
Rezolvarea problemelor blocante, atunci când apar.

 Raportarea stării actuale şi reconfigurarea planului zilnic, dacă este nevoie.

 Eliminarea testelor nerealizabile sau redundanţe în ordinea inversă a priorităţilor
(mai întâi testele de prioritate mică).
 Metricile controlului
o Numărul de cazuri de test (planificate/rulate, trecute/picate)
o Defecte (găsite, reparate)
o Acoperire
 
 structurală: măsura până la care testele acoperă structura (cod, subsisteme sau
componente)

5

comportamentală: măsura  până la care testele acoperă comportamentul sistemului
(riscuri, operaţii, activităţii, funcţii)
 Raportarea problemelor: defecte rămase în sistem, riscuri identificate, ș.a.
Necesitatea
Planificarea este influenţată de practicile interne ale organizaţiei, scopul testării,
obiective, riscuri, constrângeri, disponibilitatea resurselor. Cu cât planificarea este mai avansată,
cu atât procesul de planificare aduce mai multe informaţii şi detalii. Planificarea este o activitate
continuă şi se realizează de-a lungul vieţii produsului, pentru a recunoaşte riscurile la timp şi a
ajuta planificarea. Planul de testare reprezintă abordarea generala a unui test. În multe feluri,
planul serveşte ca un rezumat al activităţilor de testare ce vor fi executate.
Arată cum testele vor fi organizate şi defineşte toate nevoile testării, ce trebuie îndeplinite
pentru a duce la bun sfârşit un test. Planul este valoros mai ales pentru că nu este un document
dificil de urmărit, astfel că echipa de ingineri şi manageri îl pot inspecta. Partea cea mai mare a
efortului planului de testare este axată pe crearea cazurilor de testare.
- Testarea de performanță – noțiuni de bază
Testarea de perfomanță reprezintă procesul de testare software în care are loc testarea
vitezei de răspundere, stabilității, fiabilității, scalabilității și utilizării resurselor în cadrul unui
anumit volum de lucru. Principalul scop al acestui proces este identificarea și eliminarea
blocajelor de performanță apărute într-o aplicație software.
În linii generale, testarea performanței poate avea diferite scopuri, cum ar fi:
 Demonstrarea faptului că sistemul îndeplinește criteriile de performanță;

 Compararea a două sisteme pentru a găsi care operează mai bine;

 Stabilirea unor părți ale sistemelor care cauzează scăderea nivelului de performanță.
Pe lângă cele 3 criterii generale de testare a performanței mai pot fi adăugate două
tipuri(Figura 1.1):
● Testarea încărcării – lansării – supra-încărcării;
● Testare de stres;
● Testarea stabilității;
● Testarea în impulsuri (spike testing);
● Testare în configurație (configuration testing).
Fig. 1.1 Procesul de testare a performanței

Testarea în impulsuri. După cum sugerează și numele, se realizează prin simularea creșterii
sau descreșterii bruște a sarcinii generate de un interval larg a numărului de utilizatori și
evaluarea comportamentului sistemului. Scopul este de a determina dacă performanța va fi
afectată, atunci sistemul va ieși din funcțiune sau dacă va putea face față schimbărilor supuse.
Testarea în configurație este o altă variantă a testării de performanță. În locul testării
performanței prin perspectiva încărcării, se testează efectele schimbării de configurație din
mediul programului asupra comportamentului și performanței.

● Etapele testării performanței


Metodologia adoptată pentru testarea performanței are o varietate vastă pe când obiectivul
principal rămâne același. Potrivit Microsoft Developer Network metodologia de testare constă
din următoarele pași:

Identificarea
Identificare criteriilor de Planificare și Configurarea
mediului de testare acceptare a proiectarea testelor mediului de testare
performanței

Analiza rezultatelor Implementarea


configurarea și Executarea testului proiectului de
retestarea testare

Fig. 1.2 Procesul de testare a performanței

1) Identificare mediului de testare.


Identificarea mediului fizic de testare și mediului de producere are loc cu atât mai bine cu
cât instrumentele și resursele sunt accesibile echipei de testare. Mediul fizic include elementele
hardware, software și configurațiile network. Având cunoștințe profunde în ceea ce privește tot
mediul de testare de la început permite o planificare și proiectare a testării mai eficiente și ajută
la identificarea problemelor în primele etape ale proiectării. În careva situații, acest proces
trebuie să fie repetat pe parcursul ciclului de viață al proiectului.
2) Identificarea criteriilor de acceptare a performanței.
Aceasta presupune identificarea timpului de răspundere, capacității de producție, precum
și scopurile, și restricțiile de utilizare a resurselor. După regulă, timpul de răspundere reprezintă
o problemă pentru utilizatori, capacitatea de producție este o problemă de afaceri, iar utilizarea
resurselor este o problemă de sistem. În plus, determinarea criteriilor de succes al proiectului
care nu pot fi luate în considerare de aceste scopuri și restricții. Spre exemplu, utilizarea testării
performanței pentru a aprecia care combinație de setări ale configurației va influența obținerea
unor caracteristici dorite.
- Planificare și proiectarea testelor.
La această etapă se identifică scenariile-cheie, se determină schimbările între utilizatori
reprezentativi și modul de simulare a acestor schimbări, se definesc datele testării și se stabilesc

2
metricile pentru colectare. Apoi, se consolidează informația în una sau mai multe modele de
utilizare a sistemului pentru a fi implementat, executat și analizat.
4) Configurarea mediului de testare.
Are loc pregătirea mediului de testare, a instrumentelor și resurselor necesare pentru
îndeplinirea fiecărei strategii, întrucât funcțiile și componentele devin valabile pentru testare.
5) Implementarea proiectului de testare.
Presupune dezvoltarea testării de performanță în conformitate cu proiectarea testării.
6) Executarea testului.
Are loc rularea și monitorizarea testării. Se execută testele validate pentru analiză, se
monitorizează testul și mediul testării.
7) Analiza rezultatelor, configurarea și re-testarea.
Această etapă constă din analizarea, consolidarea și distribuirea datelor despre rezultatele
obținute, modificarea setărilor și testarea repetată.

Intrumentele testării performanței


Din punct de vedere ale instrumentelor utilizate, testarea performanței se divizează în două
categorii de bază: scenariul performanței și monitorizarea.
Scenariul performanței presupune crearea sau scrierea fluxurilor de lucru ale proceselor de
afaceri. La această parte se utilizează o largă varietate de instrumente precum: HP LoadRunner,
NeoLoad, Apache JMeter, Rational Performance Tester, Silk Performer, Flood ș.a.
Fiecare instrument menționat folosește sau limbaj de programare sau o formă de
reprezentare vizuală de creare și simulare a fluxurilor de lucru ale utilizatorilor finali.
Majoritatea conțin funcția ”Record & Replay” cu care tester-ul va lansa instrumentul de testare,
îl va conecta cu un browser și va fixa toate tranzacțiile de rețea care apar între client și server. În
acest sens, este dezvoltat un scenariu care poate fi îmbunătățit/modificat pentru a simula diferite
scenarii de afaceri.
Monitorizarea performanței. Cu ajutorul acesteia, comportamentul și caracteristicile de
răspundere ale aplicației sunt supuse controlului. Parametrii care sunt de obicei monitorizați în
timpul testării sunt:
Utilizarea CPU;
Utilizarea memoriei;
Utilizarea rețelei.
Pentru determinarea cauzei exacte a problemei, programatorul utilizează instrumente de
profilare(stabilire în linii generale a obiectivului de bază al producției) pentru a stabili ce părți ale
dispozitivului sau ale software-ului contribuie cel mai mult la performanță scăzută.

3
4. Studiu de caz
Acest studiu de caz reprezintă un scenariu de dezvoltare a testului de performanță pentru
măsurarea utilizării procesorului folosind programul Maximo Asset Management implementat de
compania IBM.
Compania „A” plănuiește să implementeze programul Maximo Asset Management cu o
personalizare amplă. Pentru a asigura o implementare de succes, compania „A” dezvoltă și
rulează teste de performanță.
Descriere
Compania „A” are ca scop să folosească programul dat pentru gestiunea activelor,
cumpărări, urmărirea comenzilor efectuate. Din cauza proceselor specifice de afaceri, compania
„A” deține o implementare personalizată care utilizează fluxuri automatizate de lucru.
Utilizatorii companiei folosesc următoarele componente:
 Active;

 Cereri de achiziție;

 Comenzi de achiziție;

 Urmărirea comenzilor.
Primul pas: Determinarea obiectivelor de măsurare
Echipa de implementare al companiei „A” iau în considerare întrebarea-cheie de afaceri și
acordă prioritate riscurilor, recompenselor și costurilor în implementare. Pe baza cercetărilor,
echipa de implementare stabilește că utilizatorilor nu le place atunci când tranzacțiile din
aplicațiile web durează mai mult pentru a se efectua. Interviurile realizate cu grupuri anumite
determină faptul că utilizatorii devin frustrați atunci când o tranzacție durează mai mult de 2
secunde pentru a răspunde.
Echipa de gestionare a serverelor de la Compania „A” stabilește că, dacă utilizarea
procesorului rămâne sub 80% pentru o încărcare a utilizatorilor țintă pe sistem, atunci procesorul
poate furniza resurse adecvate pentru ca aplicațiile să funcționeze la nivelul dorit. Această
valoare poate gestiona, de asemenea, creșteri ocazionale în procesare, cum ar fi în timpul
procesării pentru sfârșit de lună, fără a influența asupra timpului de răspuns. Pe baza mărimii
companiei, echipa de gestionare a serverului identifică 950 de utilizatori ca sarcină simultană
țintă.
Pasul doi: Dezvoltarea cazurilor de utilizare
Echipa de implementare ia în considerare comportamentul utilizatorilor pe parcursul zilei.
Aceasta identifică că, în general, utilizatorii se conectează după ce sosesc dimineața. Utilizatorii
realizează de obicei un set de activități de lucru și apoi se deconectează. Echipa de implementare

4
estimează că fiecare utilizator finalizează un caz de utilizare de aproximativ 20 de ori într-un
interval de o oră.
Pentru a aproxima comportamentul de conectare și deconectare, echipa de implementare
intenționează să creeze cazuri de utilizare în care utilizatorii de test automat se conectează,
rulează șase iterații ale unui caz de utilizare și apoi se deconectează. Utilizatorii de test automat
se conectează din nou și repetă ciclul. O pauză de 5 până la 10 secunde este încorporată în pașii
din scenariului pentru a reprezenta ratele reale de procesare ale utilizatorilor.
Echipa de implementare identifică cazurile de utilizare care sunt necesare pentru a testa
implementarea. Echipa atribuie, de asemenea, factori de volum pentru fiecare caz de utilizare.
Factorul de volum reprezintă numărul de utilizatori automatizați care rulează fiecare caz de
utilizare.
Tabelul 4.1 Cazuri de utilizare identificare pentru testare în Compania „A”
Identificator Factor
Descriere
caz. de utiliz. volum, %
AS01 Căutarea activelor și examinarea informațiilor despre siguranță 20
PO01 Crearea unei cereri de achiziție, apoi crearea unei comenzi de
5
achiziție pe baza cereri de achiziție.
PO02 Modificarea statutului a comenzii ”În curs de desfășurare” 5
PO03 Primirea comenzii 5
PO04 Închiderea comenzii de achiziție 5
WF01 Crearea unei comenzi de lucru și direcționarea acesteea prin
12
aplicația Workflow
WF02 Vizualizarea unei comenzi de lucru și direcționarea acesteea prin
12
aplicația Workflow pentru aprobare
WF03 Emiterea unui element al unei comenzi de lucru și direcționarea
12
acestuia prin aplicația Workflow
WF04 Adăugarea forței de muncă la o comandă de lucru și direcționarea
12
comenzii prin aplicația Workflow pentru finalizare
WF05 Trecerea unei comenzi de lucru prin aplicația Workflow pentru
12
închidere.

Pasul trei: Elaborarea testelor


Echipa de implementare înscrie fiecare caz de utilizare într-un caz de testare. Fiecare caz
de test listează fiecare etapă necesară pentru a rula testul. Tabelul următor oferă un exemplu de
caz de testare pentru cazul de utilizare AS01, care caută active și apoi examenează informațiile
despre siguranță.

5
Tabelul 4.2 Cazuri de testare de căutare a activelor și examinare a informației despre
siguranță
Operațiune Descriere Rezultatul așteptat
AS01_01_D_Launch Porniți Maximo Asset Management Este afișat ecranul Bun
venit la Maximo
AS01_02_D_Logon Introduceți numele de utilizator Se afișează Start Center
ASSET0001 și parola maxasset.
Faceți clic pe Sign In
Începerea buclei pentru elemente multiple de lucru
AS01_03_D_GoTo Faceți clic pe Go To Se afișează meniul Go To
AS01_04_D_LaunchAssets Selectați Assets > Assets Este afișată aplicația
Assets
AS01_05_D_EnterAsset În câmpul Asset, introduceți CAC și Fundalul pentru câmpul
Prefix apăsați tasta Tab Asset se schimbă în alb.
Cursorul se deplasează la
câmpul următor
AS01_06_D_FindAsset Faceți clic pe pictograma Filter Este afișată o listă care
Table listează toate activele
care au CAC (Customer
acquisition cost) în
numele lor
Crearea buclelor de până la 9 ori pentru a selecta o pagină aleatorie de date
AS01_07_D_NextPage Faceți clic pe pictograma Next Page Este afișată următoarea
pagină cu rezultatele
activelor
Finisarea buclei pentru datele paginii
AS01_08_D_SelectAsset Selectați un număr de activ aleatoriu Sunt afișate detaliile
pentru activul selectat
AS01_09_D_TabSafety Selectați fila Safety Se afișează fila Safety
AS01_10_D_ReturnTo Faceți clic pe Start Center Este afișat Start Center
StartCenter
Finisarea buclei pentru elemente multiple
AS01_11_D_Logoff Faceți clic pe Sign out Deconectarea este
finalizată. Este afișat
ecranul Bun venit la
Maximo.

Pasul patru: Definirea mediului de testare


În etapele inițiale de planificare, echipa de implementare discută dacă costul unui mediu de
testare identic cu mediul de producție este o cheltuială admisibilă. În cele din urmă, echipa de
implementare decide că riscurile unui mediu de testare inadecvat depășesc orice economii
potențiale de costuri. Prin urmare, mediul de testare al companiei „A” este un duplicat exact al
mediului de producție.
În pregătirea pentru implementare, datele existente din sistem pe care Maximo Asset
Management este programat să le înlocuiască sunt migrate în mediul de testare. Migrarea datelor
asigură faptul că echipa este capabilă să migreze datele existente și oferă, de asemenea, un volum
real și o structură a datelor din baza de date, care este apoi utilizată pentru testarea performanței.
După implementarea inițială în producție, echipa poate testa modificări suplimentare în
mediul de testare. Asemănările dintre mediile de testare și producție oferă un grad ridicat de
încredere că rezultatele similare pot fi obținute atunci când modificările suplimentare sunt mutate
în mediul de producție.
Pasul cinci: Rularea testelor
Echipa de implementare poate înregistra acum testul pentru exemplul de caz de testare și
poate repeta procesul pentru a dezvolta cazuri de testare pentru toate cazurile de utilizare. Echipa
de implementare utilizează un instrument de testare a performanței pentru a crea cazurile de
testare. După ce toate testele sunt înregistrate și depanate, echipa de implementare rulează
testele.
Pentru a afla cum funcționează sistemul la diferite niveluri de încărcare, echipa de
implementare începe testul cu 750 de utilizatori simultani. Încărcarea utilizatorului este mărită cu
încă 50 de utilizatori după un interval de 30 de minute. Creșterea numărului de utilizatori se
repetă până când 950 de utilizatori simultani sunt pe sistem. Testul este configurat pentru a
conecta un utilizator virtual la fiecare 2000 de milisecunde până când utilizatorii de la fiecare
nivel de încărcare sunt conectați. Acest proces este destinat să elimine procesarea suplimentară
necesară pentru a crește încărcarea.
Pasul șase: Analiza rezultatele testelor
După executarea testelor și compilarea datelor, echipa de implementare extrage timpul de
răspuns și rezultatele de utilizare a procesorului într-o foaie de calcul. Apoi se generează un
grafic rezumat pentru a identifica dacă sunt îndeplinite criteriile de performanță. Următorul
grafic prezintă un exemplu de rezultate ale utilizării:
Fig.4.1 Exemplu de rezultate ale testelor de performanță pentru utilizarea procesorului

În graficul rezultat, timpul mediu de răspuns este sub 2 secunde. Utilizarea procesorului pe
serverul bazei de date rămâne sub 80% la încărcarea țintă a 950 de utilizatori simultani. Cu toate
acestea, procesorul serverului de aplicații depășește 80% utilizare cu o încărcare de 850 de
utilizatori simultani. Prin urmare, criteriile testului de performanță nu au fost îndeplinite.
Echipa de implementare trebuie să investigheze pentru a determina dacă problema utilizării
excesive a procesorului poate fi rezolvată prin reglarea setărilor legate de performanță sau
modificări ale fluxurilor de lucru automatizate. Echipa de implementare poate decide, de
asemenea, dacă sunt necesare resurse suplimentare de procesor pentru a îndeplini criteriile de
performanță în implementarea producției.
Concluzie
Testarea performanței trebuie să fie o prioritate majoră înaintea lansării oricărui
program(în dependență de domeniu). Aceasta trebuie să fie realizată încă la începutul etapei de
dezvoltare pentru a detecta defectele mai devreme și pentru a satisface necesitățile utilizatorilor,
economisind timp și bani.
Problemele care ar putea fi întâlnite pe parcursul testării sunt:
Configurarea și gestionarea datelor;
Crearea testelor de performanță care să corespundă cât mai îndeaproape
comportamentului real al mediului înconjurător;

8
Scalarea testelor pentru a corespunde capacității disponibile a mediului de testare și
sarcinilor utilizatorului pentru a obține rezultate semnificative ale performanței;
Modelarea proceselor de fundal care rulează pe mediul real și poate afecta performanța;
Monitorizarea activității de mediu pentru a identifica situațiile în care sunt probleme de
performanță sau „blocaje”;
Furnizarea de informații semnificative și acționabile în rapoarte;
Identificarea tipurilor corecte de testare pentru a rula.
Însă, pentru asigurarea maximă a vitezei de răspuns, scăderea numărului de greșeli,
determinarea problemelor cu baza de date și crearea website-urilor sau aplicațiilor sigure și
rapide, este necesar de a stabili obiective clare de testare, alegând între timp, instrumentele
corecte de testare software, a infrastructurii și tehnologiilor

S-ar putea să vă placă și