TDD vs Unit Testing
Tocmai am terminat de citit azi noapte Test Driven Developement by example de Kent Beck .. O carte relativ interessanta (din pacate insa, un capitol destul de important e implementat in python, iar eu n-am avut rabdare sa invat python "on the fly" asa ca am cam sarit peste o mare parte a cartii). Chiar daca nu e atat de suculenta precum cartea lui de extreme programming, Test Driven Developement by example m-a pus putin pe ganduri. La un moment dat, kent arunca o vorba intr-o doara : "The problem with driving development with small-scale tests (I call them "unit tests," but they don't match the accepted definition of unit tests very well) is that you run the risk of implementing what you think users want, but having it turn out not to be what they wanted at all."Nu contextul ma intereseaza (acela ca fiecare clasa in sine poate sa functioneze perfect, insa aplicatia poate sa fie ratata - acelasi lucru il remarcase si Roy la TechEd) - cat ma intereseaza afirmatia ca testele scrise in TDD "nu prea sunt unit teste". Aparent, potrivit lui Kent Beck, exista o diferenta subtila intre testele din test driven developement si unit testing. Dar care ar fi asta? Kent nu pare sa revina la subiect iar eu nu pot sa fac decat speculatii.Asemanarile sunt clare - in forma - ambele genuri de teste arata la fel si sunt scrise folosind aceleasi framework-uri de testare (NUnit spre exemplu).Scopul lor insa pare diferit.Daca unit testing-ul isi propune un code coverage cat mai mare (optim 100%, dar sub 90% se considera ca este inutil), test driven developement nu incearca sa testeze codul, ci e doar un mod de a ghici interfetele potrivite pentru componentele pe care le lucrezi .. o alta modalitate de a face design .. design dupa miros (sau dupa ureche) daca vreti. Gata, ma pot relaxa, nu e nevoie sa ma mai simt vinovati ca n-am acoperit toate cazurile posibile atunci cand am incercat TDD.Perspectiva din care se sciu testele in cele doua metodologii este oarecum diferita. Unit testele, care vor acoperi toate code path-urile posibile, trebuie sa tina cont de implementarea interna a codului testat. Nu poti acoperi toate code path-urile daca nu stii foarte bine de ele. Unit Testele sunt o metoda de a asigura calitatea.Pe de alta parte, Test Driven Developement-ul pare sa priveasca problema mai curand din punctul de vedere al testarii componentei, a interfetei ei. Testele din TDD ar trebui sa ramana valabile (si neafectate) de schimbarile interne in componenta (refactorizarile). TDD-ul trebuie sa fie cat mai putin cuplat de codul pe care il testeaza.Care dintre practici e mai utila ? TDD sau Unit Testing-ul ? Luate ad-literam, nici una dintre ele nu este o metoda de a asigura 0% defects. De ce ?Daca urmaresti doar acoperirea mecanica a tuturor cailor prin cod (toate if-urile au fost calcate si pe ramura de then si pe ramura de else, toate buclele au fost rulate, etc), totusi Unit Testing-ul nu te poate scapa de erorile de logica introduse in formule. Spre exemplu, implementarea functiei factorialint Factorial(deNumar) {return 1;
poate fi corecta daca este testata cu valoarea 1, iar code coverage-ul va indica 100%. Insa implementarea e evident gresita. (Cazul e cam extrem, dar ideea ramane aceeasi : codul poate sa fie gresit dar greseala sa nu iasa in evidenta decat la anumiti parametrii).Altfel zis, 100% code coverage nu e o asigurare impotriva bug-ului .. In cel mai bun caz, te poate asigura ca nu-ti apar erori la run-time in cazul limbajelor (abordarilor) care nu sunt 100% type safe. Singura modalitate de a te asigura ca nu ai bug-uri este sa testezi 100% din code paths si 100% din parametrii posibili de apelare - ceea ce este absurd - pentru ca, spre exemplu, pentru functia factorial, ar insemna ca datele de verificare ale testului sa fie valorile precalculate ale tuturor factorialelor posibile (o infinitate).
Pe de alta parte, TDD-ul cred ca nu-si propune sa testeze codul sau sa izoleze bug-uri. Scopul principal al TDD este sa te indrume, pas cu pas, spre alegerea corecta a interfetelor, spre un design mai bun. E drept, avem nevoie de o acoperire cat mai justa cu teste (in sensul de Unit Teste) pentru a construi acea plasa de siguranta pentru clipele cand facem refactorizari. Si daca aceste teste nu acopera 100% din cazuri, la refactorizare apare riscul introducere unor bug-uri care sa nu fie depistate .. insa in aceeasi masura, apare si riscul corectarii unor bug-uri care nu erau depistate (la drept vorbind, refactorizarile ne duc la un cod mai simplu si mai clar, iar gandacii se feresc de locurile insorite - un cod mai simplu e mai putit susceptibil la bug-uri).
poate fi corecta daca este testata cu valoarea 1, iar code coverage-ul va indica 100%. Insa implementarea e evident gresita. (Cazul e cam extrem, dar ideea ramane aceeasi : codul poate sa fie gresit dar greseala sa nu iasa in evidenta decat la anumiti parametrii).Altfel zis, 100% code coverage nu e o asigurare impotriva bug-ului .. In cel mai bun caz, te poate asigura ca nu-ti apar erori la run-time in cazul limbajelor (abordarilor) care nu sunt 100% type safe. Singura modalitate de a te asigura ca nu ai bug-uri este sa testezi 100% din code paths si 100% din parametrii posibili de apelare - ceea ce este absurd - pentru ca, spre exemplu, pentru functia factorial, ar insemna ca datele de verificare ale testului sa fie valorile precalculate ale tuturor factorialelor posibile (o infinitate).
Pe de alta parte, TDD-ul cred ca nu-si propune sa testeze codul sau sa izoleze bug-uri. Scopul principal al TDD este sa te indrume, pas cu pas, spre alegerea corecta a interfetelor, spre un design mai bun. E drept, avem nevoie de o acoperire cat mai justa cu teste (in sensul de Unit Teste) pentru a construi acea plasa de siguranta pentru clipele cand facem refactorizari. Si daca aceste teste nu acopera 100% din cazuri, la refactorizare apare riscul introducere unor bug-uri care sa nu fie depistate .. insa in aceeasi masura, apare si riscul corectarii unor bug-uri care nu erau depistate (la drept vorbind, refactorizarile ne duc la un cod mai simplu si mai clar, iar gandacii se feresc de locurile insorite - un cod mai simplu e mai putit susceptibil la bug-uri).

0 Comments:
Post a Comment
<< Home