Sunteți pe pagina 1din 16

UNIVERSITATEA DIN CRAIOVA

FACULTATEA DE AUTOMATIC, CALCULATOARE


I ELECTRONIC

REFERAT LA DISCIPLINA
TESTAREA SISTEMELOR
NCORPORATE

Profesor Coordonator:
Prof. dr. ing. Nicolae ENESCU

Masterand:
Eduard DRGHICI

CRAIOVA
2016

UNIVERSITATEA DIN CRAIOVA


FACULTATEA DE AUTOMATIC, CALCULATOARE
I ELECTRONIC

TESTAREA UNITAR

Profesor Coordonator:
Prof. dr. ing. Nicolae ENESCU

Masterand:
Eduard DRGHICI

CRAIOVA
2016
2

Cuprins

Testarea Unitar. Generalitai. .. pag. 4


Ce este Testarea Unitar . pag. 5
Platforme de testare . pag. 6
Testele unitare. Caracteristici pag. 7
Dublele de testare pag. 10
Concluzii .. pag. 15
Bibliografie .. pag. 16

Testarea Unitar
Testarea este necesar si pentru programele scrise ntr-un limbaj static (pentru care se
fac verificri de corectitudine la compilare) dar, mai ales, pentru programe scrise ntr-un
limbaj dinamic si care nu beneficiaz de verificrile efectuate de un compilator.
In cursul dezvoltrii unei aplicatii codul evolueaz (fie datorit modificrii cerintelor, fie
prin reproiectare sau prin refactorizare), dar prin teste ne putem asigura c acest cod
modificat continu s respecte cerintele impuse ( c este corect). Chiar dac scrierea de teste
necesit un efort suplimentar, ele ne permit s avem ncredere c programul va functiona si
dup modificri.
Testarea programelor este bine s se fac pe msura dezvoltrii acestora si nu dup ce
programele au fost scrise. Cu ct mai devreme sunt detectate erorile, cu att e mai bine.
Se pot deosebi urmtoarele tipuri de teste:
- Teste unitare, care verific fiecare unitate de program separat de celelalte (o unitate poate fi
o metod, o clas, o secvent de apeluri de metode).
- Teste de integrare, care verific interactiunile dintre unittile de program (testate separat).
- Teste de sistem, care verific toata aplicatia.
- Teste de acceptare, care verific modul cum programul rspunde cerintelor beneficiarilor.
Testele trebuie s fie rapide, repetabile, izolate si automatizate: rapide pentru a nu
descuraja repetarea testelor dup orice modificare de cod, izolate astfel ca esuarea unui test s
nu aib efecte asupra altor teste, repetabile cu aceleasi rezultate indiferent de rulrile
anterioare ale testului sau de interactiunile firelor de executie concurente din aplicatie,
automatizate pentru
a simplifica executarea lor si analiza rezultatelor.
Chiar dac nu se scriu teste pentru toate metodele din toate clasele aplicatiei, testele
trebuie s acopere prtile cele mai importante si mai sensibile din aplicatie.
Dezvoltarea bazat pe teste (TDD=Test Driven Development) este metodologia n care
testele unitare se scriu nainte de a scrie codul unittilor testate. Scrierea timpurie a testelor
este o activitate de proiectare , deoarece necesit ntelegerea cerintelor si poate conduce la
refactorizrea codului. TDD impune gndirea codului n functie de intentiile lui si nu n
functie de implementare.
4

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 unitti de cod poate fi de dou feluri:
- Unitatea testat depinde de alte unitti
- Alte unitti de cod depind de unitatea testat
Este posibil ca unitatea de care depinde secventa testat (o resurs) s nu fie nc
disponibil, sau s fie costisitor de utilizat sau s fie impredictibil n comportare. In aceste
cazuri se folosesc obiecte surogat de tip "stub" sau "mock" n locul unui "colaborator" din
aplicatia real.
Obiectul surogat poate corespunde unui singur obiect din aplicatia final sau unei
componente, sau unui nivel sau unui subsistem din aplicatie.
Un obiect "stub" mimeaz partial comportarea unui obiect real (indisponibil),prin
transmiterea unui rspuns corespunztor la fiecare cerere primit (printr-un apel de metoda),
fr a tine seama de succesiunea acestor cereri.
Un obiect "mock" mimeaz mai bine comportarea obiectului real, pentru c tine seama de
secventa apelurilor si de numrul lor, deci simuleaz ntreaga interactiune 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.
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 dect comanda Run pentru executia aplicatiei) si prin afisarea n mod
grafic a rezultatelor testelor. Atunci cnd testele esueaz (fails) nu se afiseaz toat
secventa de apeluri de metode care a condus la eroare AssertionError (asa cum se ntmpl
n linie de comand sau cnd se foloseste un IDE mai simplu care nu are regim special pentru
testare unitar).
Ce este testarea unitar?
Termenul de 'testare unitar' se refer la testarea individual a unor uniti separate
dintr-un sistem software. n sistemele orientate spre obiecte, aceste 'uniti' sunt de regul
clase i metode.
5

Elementele de testare unitar, pun la dispoziie unelte pentru a nregistra i repeta


teste, pentru ca testele unitare sa poat fi repetate uor mai trziu (de regul cnd se schimb
o parte din sistem), astfel nct dezvoltatorul s fie convins ca noile modificri nu au stricat
vechea funcionalitate. Acest lucru e cunoscut ca testare regresiv.
Conceptele testrii unitare i testrii regresive sunt destul de vechi, dar popularitatea
lor a crescut brusc de curnd, dup publicarea metodologiei de programare eXtreme1 i dup
apariia unei unelte de testare unitar pentru Java: JUnit.
JUnit este un cadru de testare regresiv scris de Erich Gamma i Kent Beck.
Testarea unitar se refer la scrierea unor buci de cod, denumite cod de testare, care
valideaz codul de producie. Testarea majoritii aplicaiei devine aadar automat.
Istorie: programatorii cred adesea n mod eronat c unit testing este o practic nou.
n realitate, era folosit chiar de pe vremea calculatoarelor mainframe cu cartele perforate. Pe
vremea aceea, debugging-ul era foarte dificil din cauz c implica citirea unor foi lungi de
zeci de metri imprimate cu rezultatul programului i informaii despre execuie. Testele
automate care rulau n acelai timp cu programul ddeau informaii mult mai bogate legate de
sursa greelilor.
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) implementeaza un singur caz de testare;
Unitatile sunt testate independent unele fata de altele;
Pentru fiecare unitate se scriu, in mod uzual, mai multe teste unitare;

Ce facem cu testerii?
O temere ntlnit adesea este c testerii i vor pierde locul de munc o dat cu
introducerea testrii automate. n realitate, testerii devin mult mai importani pentru c acum
doar ei pot descoperi problemele ascunse, greu sau imposibil de gsit prin teste automate. Ei
ajut s creasc probabilitatea c totul funcioneaz corect de la 80+% la aproape 100%.
Testele unitare au cteva caracteristici importante:

fiecare test valideaz un comportament din aplicaie;

ruleaz foarte repede, maxim n cteva minute;

sunt foarte scurte i uor de citit;

ruleaz la apsarea unui buton, fr configurri suplimentare.

Pentru a fi rapide, testele unitare folosesc adesea aa-numitele "duble de testare". La fel
cum piloii de avioane nva ntr-un simulator nainte de a se urca n avion, testele unitare
folosesc buci de cod care seamn cu codul de producie, dar n realitate folosesc doar la
teste. Stub-urile i mock-urile sunt cele mai ntlnite duble de testare, existnd multe altele
mai puin folosite.
Un stub este o dubl de testare care ntoarce valori. Stub-ul este similar cu o simulare
foarte simpl: atunci cnd apei un buton, apare o valoare. n cod, un stub poate arta astfel:

class PaymentServiceStub implements PaymentService{


public boolean valueToReturnOnPay;

public boolean pay(Money amount){


return valueToReturn;
}
}

class PaymentProcessorTest{

@Test
public void
paymentDoneWhenPaymentServiceAcceptsPayment(){
7

PaymentServiceStub paymentServiceStub =
new PaymentServiceStub( );

paymentServiceStub.valueToReturn = true;
PaymentProcessor paymentProcessor =
new PaymentProcessor(paymentServiceStub);

paymentProcessor.processPayment(
Money.RON(100));

assertPaymentWasCorrectlyPerformed(
paymentProcessor);
}
}
Un mock este o dubl de testare care valideaz colaborarea ntre clase. Mock-ul
valideaz apeluri de metode, cu anumii parametri, de un anumit numr de ori. Din aceast
cauz, un mock poate fi folosit i la validarea apelurilor de metode care nu ntorc valori.

class PaymentServiceMock
implements PaymentService{

public boolean payWasCalled;


public Money actualAmount;

public void pay(Money amount){


actualAmount = amount;
payWasCalled = true;
}
}

class PaymentProcessorTest{
8

@Test
public void
paymentServiceCalledOnPaymentProcessing(){

PaymentServiceMock paymentServiceMock =
new PaymentServiceMock();

PaymentProcessor paymentProcessor =
new PaymentProcessor(paymentServiceMock);

Money expectedAmount = Money.RON(100);

paymentProcessor.
processPayment(expectedAmount);

assertTrue(paymentServiceMock.payWasCalled);
assertEquals(expectedAmount,
paymentServiceMock.actualAmount);
}
}
Utilizarea de obiecte surogat (Mock Objects)
Majoritatea unittilor de program supuse testelor depind de alti colaboratori care pot fi
unitti locale (alte metode din aceeasi clas), pot fi parametri ai metodelor testate sau pot fi
chiar metode aflate n alt calculator (remote). Pentru a testa unitti cu dependente de alte
unitti trebuie nlocuiti 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) utiliznd un framework ca EasyMock, JMock, s.a.

Clasa surogat scris manual trebuie s aib aceleasi metode cu clasa pe care o
nlocuieste; acest lucru se poate face prin extinderea clasei colaborator si redefinirea
metodelor sau prin implementarea unei interfete definite n scopul testrii.
In Java, pentru a facilita trecerea de la teste unitare la teste de integrare se folosesc fie
interfete (pentru comunicarea cu obiectele surogat), fie obiecte de tip proxy, care
intercepteaz cererile si le dirijeaz fie ctre obiecte surogat fie ctre obiecte reale.
Schema urmtoare arat o interfat ntre codul testat si codul de care depinde sau codul
surogat (care nlocuieste n teste codul real).

Utilizare EasyMock n Java

EasyMock este un framework de testare pentru aplicatii 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 moq pentru .NET.

class PaymentProcessorTest{

@Test
public void
paymentDoneWhenPaymentServiceAcceptsPaymentWithMockitoStub(){

Money amount = Money.Ron(100);


10

PaymentServiceStub paymentServiceStub =
mock(PaymentService.class);

when(paymentServiceStub.pay(amount)).
thenReturn(true);

PaymentProcessor paymentProcessor =
new PaymentProcessor(paymentServiceStub);

paymentProcessor.processPayment(amount);

assertPaymentWasCorrectlyPerformed(
paymentProcessor);
}
@Test
public void
paymentServiceCalledOnPaymentProcessingWithMockitoMock(){

Money amount = Money.RON(100);


PaymentServiceMock paymentServiceMock = mock(PaymentService.class);

PaymentProcessor paymentProcessor =
new PaymentProcessor(paymentServiceMock);

paymentProcessor.processPayment(amount);

verify(paymentServiceMock).pay(amount);
}

}
Iniial 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,

11

dublele de testare au ajuns s fie folosite n toate testele unitare, dnd natere metodei
"mockiste" de testare unitar.
Testele unitare sunt scrise de programator, n timp ce implementeaz o funcionalitate.
Din pcate, cel mai ntlnit mod de a scrie teste este cndva dup ce a fost terminat
implementarea. Rezultatul este c testele sunt scrise avnd n minte cum ar trebui s
funcioneze codul i nu testarea lui.
Test First Programming este o metod de a scrie teste care implic urmtorii pai:

crearea unui design pentru implementarea funcionalitii;

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 Test First Programming, programatorii se asigur c scriu teste unitare i c
testeaz ceea ce ar trebui s rezolve, nu implementarea soluiei.
Test Driven Development (TDD) poate fi a treia metod de a scrie teste. De fapt, TDD este o
metod de a face design incremental.
Dureaz mai mult cnd scriu teste!
Studiile de caz i experiena personal a programatorilor a artat c ntr-adevr,
timpul petrecut strict pe dezvoltarea unei funcionaliti crete o dat cu adoptarea unit
testing. Aceleai studii au artat c timpul petrecut pe mentenan scade drastic, artnd ca
unit testing poate aduce o mbuntire net n timpul de dezvoltare.
Acest fapt nu poate schimba percepia programatorului care trebuie s scrie mai mult
cod. De aceea, programatorii presupun adesea c per total proiectul merge mai ncet din
cauza testrii automate.

12

Cum ncep?
Este bine ca adopia unit testing s se fac cu grij, incremental, urmrind cteva puncte
importante:

Clarificarea conceptelor legate de unit testing nainte de a ncepe scrierea de teste.


Programatorii trebuie s poat "mnui" fr team unelte precum: stub-uri, mock-uri,
teste de stare, teste de colaborare, teste de contract, dependency injection. De
asemenea, programatorii trebuie s neleag ce cazuri merit i trebuie testate. Exist
cteva modaliti prin care programatorii reuesc s stpneasc aceste concepte:

training specializat pe unit testing. Mozaic Works ofer un asemenea curs


(http://bit.ly/unit-testing-workshop) care a avut constant feedback de peste 9.25/10 de
la participani.

pair programming ntre un tester i un dezvoltator.

pair programming ntre un dezvoltator experimentat n unit testing i unul nceptor.


Dezvoltatorul experimentat poate fi i un coach tehnic extern.

documentarea din cri (vezi la final crii recomandate), de pe internet sau prin
participarea la evenimente de comunitate.

participarea la conferine unde se discut concepte de unit testing.

Un coach tehnic poate lucra cu programatorii, ajutndu-i s transfere informaiile


teoretice n practica de zi cu zi astfel nct productivitatea s fie ct mai puin afectat;

Testarea automat n primul rnd a celei mai importante pri din aplicaie i apoi a
funcionalitilor cu cel mai mare risc de greeal;

Folosirea strategiei de testare de tip "Piramida testelor"3pentru a elimina ct mai multe


greeli cu putin;

n cazul n care exist mult cod (legacy code), este recomandat nvarea unor tehnici
suplimentare pentru a scrie teste pe cod existent. Mai multe detalii ntr-un articol
viitor.

13

Greeli comune
Cteva greeli 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 uor de ntreinut

Abandonarea dublelor de testare, sau folosirea lor n scopuri pentru care nu au fost
create. Dublele de testare ajut la obinerea unor teste scurte i rapide.

Numele testelor nu exprim comportamentul testat. Numele testului poate da foarte


multe informaii atunci cnd 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
situaii exotice.

Cod de testare nengrijit. Codul de testare este cel puin la fel de important ca i codul
de producie, i trebuie ntreinut cu aceeai grij.

14

Concluzii

Unit testing-ul (testarea unitar) este una dintre metodele pe care un programator o
poate folosi cu scopul de a reduce numrul de greeli pe care le face cnd scrie cod.
Folosit corect, unit testing-ul poate reduce semnificativ timpul petrecut cu repararea
bug-urilor din aplicaii, reducnd ncrcarea colegilor care se ocup de suport i testare i
permind introducerea de noi funcionaliti mai repede, ceea ce conduce la competitivitate
crescut.
Dar unit testing-ul trebuie adoptat cu grij, urmnd practicile din industrie (piramida
testelor, folosirea dublelor de testare etc). Ajutorul extern (training i coaching tehnic) poate
face diferena ntre o adopie reuit i una cu probleme.
Un software craftsman stpnete unit testing i l folosete atunci cnd e nevoie s se
protejeze de greeli, fie ale sale fie ale colegilor de echip.
Aa este sigur c poate livra software fr bug-uri chiar i atunci cnd e sub presiunea
timpului. Cu condiia, evident, s nvee unit testing att de bine nct s l foloseasc cu
uurin chiar i atunci cnd e sub presiune.

15

Bibliografie

http://www.todaysoftmag.ro/article/377/din-uneltele-artizanului-software-unit-testing
http://mozaicworks.com/blog/5-common-unit-testing-problems/.

16

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