BlogNie je Test-Driven Development príliš pomalý spôsob vývoja softvéru?

Nie je Test-Driven Development príliš pomalý spôsob vývoja softvéru?

Nie je Test-Driven Development príliš pomalý spôsob vývoja softvéru? 2

Predchádzajúce články predstavili TDD a poukázali na jeho výhody. Ale nie je možné aby nejaká technika mala len samé výhody a žiadne nevýhody. Mohlo by byť takou nevýhodou napríklad viac času venovanej testom, a teda pomalý vývoj? Poďme sa na to pozrieť.


Pozývame na školenie s Pavlom Bernhauserom: Test-Driven Development, ktoré sa uskutoční 19.5.2020ONLINE o 18:00. ☞ Registrácia na školenie.

Pri tvorbe softvéru by nás mala zaujímať celková cena na vývoj a údržbu. Takže si zhrňme, čo má vplyv na cenu:

  • doba vývoja
  • chyby
  • kvalita

Rozoberme si postupne tieto body z pohľadu programovania unit testov pre hotový a otestovaný komponent a porovnajme to s programovaním komponentu prístupom TDD.

Doba vývoja

Napísať test až po produkčnom kóde je často ťažké, lebo produkčný kód nie je dizajnovaný s ohľadom na testovateľnosť. Vtedy test musí testovať veľkú funkcionalitu naraz. Nie len, že počet ciest v kóde rastie exponenciálne s jeho veľkosťou, ale vedie to aj ku náročnej príprave vstupných údajov a komplikovanému testovaniu výsledkov.

Samotný test napísaný „až po” je zvyčajne dlhý a ťažko čitateľný. Mnohokrát strávime veľa času zisťovaním, čo ten test vlastne robí a prečo pri pridaní novej funkcionality zlyháva. A keď to konečne zistíme, tak buď ho ešte viac skomplikujeme o testovanie novej funkcionality, alebo len hackneme, aby prechádzal a nová funkcionalita sa vôbec netestuje. Prípadne ešte horšie — zduplikujeme celý test, originál hackneme a kópiu nejak upravíme, aby sa nová funkcionalita testovala.

Naopak, TDD vedie k tvorbe jednoduchších testov. Aj produkčný kód ma tendenciu byť jednoduchší a lepšie rozdelený na menšie časti. To, že sme pri tvorbe čitateľného kódu komponentu a testu strávili trochu viac času nevadí. Táto investícia sa nám vráti 10-krát.

Chyby

Čím viac chýb a čím dlhšia doba uplynie od zavedenia chyby po jej opravu, tým je cena vyššia. Dôvodov je viac. Napríklad si programátor musí spomenúť, o čom bola pôvodná úloha, alebo si musí preštudovať cudzí kód. Niet nad situáciu, keď si programátor nájde chybu sám. Odpadá čas, ktorý potrebuje tester na zachytenie detailov do bug reportu — čo robil, čo sa stalo a čo očakával.

Oprava chýb, ktoré vznikli inde ako na mieste, kde sa prejavili, trvá zvyčajne dlhšie. Ako príklad si predstavme, že komponent zapíše nesprávnu hodnotu do databázy, ale problém sa ukáže až o týždeň v tlačovej zostave. Na odstránenie tejto chyby musíme najprv zistiť, či je chyba vo vstupných údajoch, pri ich spracovaní alebo v zostave. Ak sú uložené údaje nesprávne, tak asi nebude stačiť opraviť chybu v kóde, ale bude treba spraviť skript na opraviť údajov v databáze. Keby sme túto chybu objavili už pri testovaní, tak by sme nemuseli opravovať údaje v produkčnej databáze.

Testy naprogramované „až po” často netestujú všetko, lebo je to ťažké dosiahnuť. Mnohokrát testy testovaným kódom len prechádzajú, ale neoveria všetky výstupy. Hlavne, že je zelený. Toto nám dáva dva druhy falošného pocitu istoty.

Nie je Test-Driven Development príliš pomalý spôsob vývoja softvéru? 4

Za prvé, že v kóde žiadne chyby nie sú, lebo je pokrytý testami. A za druhé, ešte horšie, že môžeme bez obáv refaktorovať. Takže v produkčnom kóde môže byť skrytá chyba, ktorú test nenašiel, alebo ju v rámci refaktoringu pomohol vytvoriť.

Unit test napísaný „až po” môže byť ešte zákernejší. Programátor mohol pri programovaní testu „podvádzať” a nakúkať, čo robí produkčný kód. Výsledkom je, že ak produkčný kód obsahuje chybu, tak tú chybu môže test povýšiť na očakávanú vlastnosť.

TDD tieto problémy nespôsobuje. Keď napíšeme test dopredu, tak zvyčajne testuje malú funkcionalitu. V takej je jednoduchšie otestovať všetko. Ak si test spustíme pred naprogramovaním či úpravou produkčného kódu, tak vieme, že niečo testuje aj po tom, čo ozelenie.

Kvalita

Kvality sme sa dotkli už v predchádzajúcom bode, tak teraz sa budeme venovať druhej stránke. Tou je schopnosť rýchlo modifikovať kód vzhľadom na nové požiadavky. Opäť tu vidíme dva aspekty.

Prvým je čitateľnosť, prehľadnosť a celkové rozdelenie rolí v produkčnom kóde. Test napísaný „až po” nás netlačí do malých tried, ktoré majú jasne definované role. Takže existencia tisíc-riadkovej triedy s menom Controller, ktorý robí všetko je dosť pravdepodobná. Ak v takej triede treba niečo zmeniť, tak jej úpravou strávime viac času ako by sme potrebovali, keby by sme mohli naprogramovať novú implementáciu jednoduchého rozhrania a zaintegrovať ho niekde do existujúcej triedy.

Druhým aspektom je schopnosť unit testov umožniť alebo znemožniť robiť ľahko zmeny v kóde. Vo svojej praxi som veľakrát zažil situáciu, že upraviť produkčný kód zabralo pár minút čítania a skúmania spolu s pol hodinkou programovania. Zato pridať nové testy trvalo štyri hodiny a viac. Testy boli komplikované, lebo testovali veľkú metódu. Alebo bolo treba mockovať mnoho spolupracujúcich komponentov.

TDD vedie k menším testom aj produkčným triedam.  Samozrejme TDD negarantuje, že to budeme robiť správne. Ale zlé výsledky sú menej pravdepodobné. Programátori, čo sú zvyknutí na rýchlu spätnú väzbu pri TDD by si „všimli”, že zrazu ich TDD cyklus spomalil. Takže buď píšu komplikovaný test, alebo produkčný kód robí príliš veľa na jeden test.

Celková rýchlosť vývoja

Pri TDD sú niektoré kroky, ktoré sa zdajú ako pomalé. Napríklad to, že ku každej novej funkcionalite treba spustiť testy najmenej dvakrát. Prvý raz hneď ako sa napíše test a potom ešte raz, keď dokončíme zmenu produkčného kódu. A ak sme refaktorovali, tak aj tretí raz. Prípadne viackrát, ak máme chybu.

Ak nám spustenie testov trvá len pár sekúnd, tak stratený čas bude ľahko získaný späť po dlhšom období. Nesmieme zabudnúť, že čas potrebný na prvotné napísanie kódu je zanedbateľný s celkovým časom stráveným jeho čítaním a údržbou. Tým, že TDD vedie k lepšiemu porozumeniu špecifikácie; ku vyššej kvalite produkčného kódu aj testov; menšiemu počtu chýb nájdených neskôr; menšiemu počtu úprav a veľkých refaktoringov, tak trochu dlhší čas potrebný na prvotné napísanie stojí za to.

Ak s TDD ešte len začíname, tak nemôžeme okamžite očakávať všetky výhody. Nech sa učíme čokoľvek nové, zo začiatku budeme menej efektívni, takže sa nepokúšajme porovnávať svoj výkon počas tejto fázy s tým, ako sme boli zvyknutí pracovať dovtedy. TDD vás zo začiatku určite spomalí.

Užitočné linky

Záver

Škoda, že jediný „ľahko” merateľný aspekt vývoja softvéru je to, ako dlho trval prvotný vývoj komponentu. Úvodzovky som použil preto, že aj takéto meranie je len subjektívne a založené skôr na pocitoch ako na skutočnom porovnaní rôznych prístupov. Takto môže Test-Driven Development vychádzať ako pomalší.

Ale keď zohľadníme aj čitateľnosť, modifikácie a opravu chýb (a ich počet), tak TDD začne vychádzať oveľa priaznivejšie.

Prihláste sa na toto školenie skôr ako si vyskúšate TDD sami. Pomôže vám lepšie naštartovať.

Školenie sa uskutoční 19.5.2020ONLINE o 18:00. ☞ Registrácia na školenie.

Ďalšie Pavlove články na tému TDD:

Dobrý článok? Chceš dostávať ďalšie?

Už viac ako 6 200 ITečkárov dostáva správy e-mailom. Nemusíš sa báť, nie každé ráno. Len občasne.

Súhlasím so spracovaním mojich osobných údajov. ( Viac informácií. )

Tvoj email neposkytneme 3tím stranám. Posielame naňho len informácie z robime.it. Kedykoľvek sa môžeš odhlásiť.

Pavel Bernhauser
Pavol Bernhauserhttps://testdrivingexpert.com/
Pavel Bernhauser sa venuje programovaniu od detstva. Po skončení Elektrotechnickej Fakulty STU sa tým začal živiť a stále ho programovanie baví. Hoci už odvtedy prešlo viac ako 20 rokov. Písať unit testy ho prinútili v roku 2002. Odvtedy hľadá možnosti, ako to robiť lepšie. Čaro Test-Driven Development objavil asi v roku 2004. Najnovšie začal písať blog Test Driving Expert, kde sa venuje problematike unit testov a testovateľného dizajnu.

Čítaj ďalej: