De cele mai multe ori, dupa ce un programator finalizeaza scrierea unui “program” dupa anumite specificatii, acesta este trimis catre echipa de testare in vedere gasirii bug-urilor. Daca sunt gasite probleme, “programul” se intoarce in faza de dezvoltare pentru a fi remediate. Acest schimb intre programator si echipa de testare se poate face de un numar suficient de mare de ori pana cand toate problemele sa fie rezolvate. Pentru a evita situatia enumerata mai sus se poate folosi tehnica TDD prin care programatorul scrie teste inainte de a implementa o anumita functionalitate.
TDD (Test Driven Development) este o abordare a dezvoltarii de software prin care testele sunt scrise inainte ca softul sa fie scris. Cu alte cuvinte, este o cale de a gândi prin prisma cerințelor sau a designului înainte de a ne apuca efectiv a scrie cod funcțional.Un alt punct de vedere este că TDD reprezintă o tehnică de programare al cărui scop este acela de a scrie cod curat care funcționează. Aceasta metoda contine 3 pasi:
La o prima analiza a acestei metode ar parea ca este o pierdere de timp prin faptul ca trebuie scrise si teste si astfel dezvoltarea software-ului este incetinita. Dar aici vine marele avantaj. Dupa cum observam in pasii anteriori, scrierea unui test care esueaza este in stransa legatura cu dezvoltarea. Astfel, dupa ce scriem suficient cod pentru a face testul sa mearga (sau pana cand credem ca este suficient sa treaca testul) trebuie sa testam din nou. Avand momentele de timp, cand codul functioneaza fara erori, foarte bine stabilite in timp este mult mai usor sa revii intr-o stare in care codul este functional si sa rescrii functionalitatea ce esueaza. Astfel, se castiga timpul pierdut cu debugging-ul si cu gasirea functionalitatilor care esueaza. Mereu testul ce esueaza este ultimul si prin urmare problema este la ultima functionalitate adaugata.
Concluzii
Test-driven development nu inlocuieste metoda traditionala de testare, dar defineste o modalitate de dezvoltare a codului in vederea limitarii greselilor. Mai mult, aceasta metoda aduce avantaje de timp pentru identificarea problemelor la introducerea functionalitatilor noi, permite dezvoltarea unui cod mai mic si mai usor de inteles si faciliteaza schimbul de cunostinte din cadrul unei echipe.
In cadrul acestui laborator vom face de la 0 un proiect si vom urma toti pasii necesari pentru a dezvolta software folosind TDD.
In cadrul laboratorului de astazi vom face un program denumit sugestiv SplitBill. Acesta va lua anumite sume de bani, persoane, procentul de tips si va returna o suma de bani ce trebuie data de fiecare persoana pentru achitarea notei.
Primul din cei 3 pasi TDD a fost realizat: testul a fost scris. Dupa ce rulam acest test vom vedea faptul ca testul nu va trece intrucat noi nu avem implementata aceasta metoda in cadrul clasei. Urmatorul pas este scrierea celor mai simple linii pentru a face testul sa treaca.
Avand in vedere ca testul nostru este conceput pentru cazul in care tips-ul este 0 ceea ce avem de facut este sa returnam suma initiala:
public class Calculator { public double calculate(double amount, double tips) { return amount; } }
Pentru testul curent, dat fiind faptul ca este foarte simplu, vom omite etapa refactoring considerand ca nu avem ce modifica.
@Test public void getTotalAmountWithTips() { Calculator calculator = new Calculator(); assertEquals(85.8, calculator.calculate(78, 10)); }
public class Calculator { public double calculate(double amount, double tips) { if (tips == 0.0) { return amount; } else { var tipsAmount = amount / 100 * tips; return amount + tipsAmount; } } }
De data aceasta putem face refactoring eliminand din codul redundant:
public class Calculator { public double calculate(double amount, double tips) { var tipsAmount = amount / 100 * tips; return amount + tipsAmount; } }
JUnit ne permite sa dam argumente functiilor de testare. Folosind adnotarea @ValueSource putem adauga un array de elemente pe care sa le folosim ca argumente.
@ParameterizedTest @ValueSource(doubles = {0, 10, 100, 78, 20}) public void getTotalAmountWithTips2(Double amount) { Calculator calculator = new Calculator(); System.out.println("Amount " + amount + " with tips 10 = " + calculator.calculate(amount, 10)); }
Folosind adnotarea @CsvSource putem da mai multe argumente functiilor de testare.
@ParameterizedTest @CsvSource({ "0, 0", "10, 11", "100, 110", "78, 85.8", "20, 22", }) public void getTotalAmountWithTips3(Double amount, Double expected) { Calculator calculator = new Calculator(); assertEquals(expected, calculator.calculate(amount, 10)); }
Descarcati arhiva de aici: laborator7.zip.
Partea 1:
Partea 2: