În cartea sa, Gemba Kaizen, Masaaki Imai vorbește despre un mod de organizare a întreprinderilor care promovează îmbunătățirea continuă a calității proceselor. Autorul descrie cum organizații, indiferent de mărime sau industria în care activează, pot îmbrățișa principiile general valabile care însumează noțiunea kaizen. Această noțiune înseamnă "îmbunătățire". Când vorbim despre kaizen, vorbim despre o îmbunătățire totală. De la aprovizionare la livrare, de la muncitorul necalificat la personalul de cel mai înalt rang al organizației, toate procesele şi persoanele sunt responsabile de kaizen. Așa că ne întrebăm care sunt procesele din industria software cele mai susceptibile de a fi afectate de kaizen.
Foarte multe metodologii de gestionare a proiectelor software din ziua de azi presupun îmbunătățirea continuă a proceselor de producție. Familia metodologiilor "Agile", în general, și eXtreme Programming - XP - în special, promovează în mod deosebit aspectul îmbunătăţirii continue a proceselor. În toate procesele "agile" avem ceremonia retrospectivei, spre exemplu. Mai mult, XP admite şi chiar încurajează îmbunătățirea metodologiei însăși pentru a corespunde particularităților unui proiect sau cerințelor timpului. De aceea ne vom opri asupra XP.
Aspectul cel mai interesant al XP este non-formalismul său. Spre deosebire de alte metodologii, XP apare utilizatorilor săi mai mult ca un set de practici care, dacă sunt folosite corect și consecvent, duc la o îmbunătățire totală foarte asemănătoare cu cea prezentată în Gemba Kaizen. Deşi putem face numeroase paralele între XP şi kaizen, acum ne vom opri doar la practica XP numită Test First.
Începem prin a aminti că Test First presupune să scriem un test care eșuează înainte de a scrie implementarea. Această practică are numeroase merite când o comparăm cu abordarea clasică de a scrie teste după ce am scris implementarea. Între aceste merite le amintim cel puțin pe următoarele:
Minimizează înflorirea nejustificată a soluțiilor (over-engineering);
Ajută la optimizarea codului în termeni de cuplare/coeziune;
Impune o cadență (test-implementare);
Caracteristici ca over-engineeringul, cuplarea, cadența sau riscul apariției defectelor pot fi măsurate prin metode euristice sau statistice. Deși oportunitatea sau acuratețea măsurătorilor poate fi un subiect de discuție aprins, fapt rămâne că Test First deschide posibilitatea de a efectua măsurători într-o lume altfel impermeabilă din acest punct de vedere (mintea programatorului). Beneficiile personale care decurg din această posibilitate de a ne măsura performanțele sunt o valoare în sine. Mai mult, ne ajută şi la scrierea acestui articol întrucât kaizen are ca principiu fundamental ca acţiunile întreprinse să fie măsurabile.
Din păcate aflăm din Gemba Kaizen că pe lângă a fi măsurabile, tot fundamental pentru kaizen este ca îmbunătățirile să fie și vizibile. În plus, pentru a vorbi de livrarea produsului în timp real (altă practică Gemba Kaizen - "just in time delivery" sau JIT) am avea nevoie de metrici cum ar fi timpul de lansare pe piaţă (TTM). Dacă măsurarea îmbunătățirilor este posibilă măcar parţial folosind Test First, această practică nu are în vedere vizibilitatea lor sau timpul de lansare pe piață. Spre exemplu, îmbunătățirile nu sunt vizibile cât timp nu este specificată o bornă de la care scrierea testelor se oprește și implementarea începe. Urmând doar Test First putem fi puşi în situaţia unor teste care eşuează în mediul de integrare. Mai putem vorbi de o vizibilitate a îmbunătăţirilor în acest context? Lipsa unor reguli în acest sens ne lasă în incertitudine, făcând ambiguu rezultatul efortului de implementare.
În ceea ce priveşte livrarea JIT, calitatea codului produs influenţează momentul lansării pe piață. E lesne de înţeles că o implementare pentru care testele eşuează va fi trimisă pentru corectare. S-ar putea spune că putem să ne bazăm pe statistică pentru a măsura timpul de lansare. Acest lucru este fals pentru că în lipsa unor reguli, modul în care se face implementarea prima oară nu coincide cu modul în care se implementează corectura soluţiei iniţiale. Aşadar, nu avem baze pentru a corobora măsurătorile şi a recurge la statistică. Să ne aducem aminte că Test First cere doar ca testele să fie scrise înaintea implementării. Nu există nicio regulă privind calitatea codului sau modul în care trebuie făcută implementarea.
În contextul de mai sus, o practică superioară Test First este Test Driven Development (TDD). Pe lângă dictonul de a scrie testele înaintea implementării, această practică umple şi lipsurile celei dinainte în materie de formalism şi calitate a codului. Ea se bazează pe următoarele patru reguli:
Se scrie un test care eșuează (implică rularea tuturor testelor);
Se scrie implementarea care promovează testul (implică rularea tuturor testelor);
Se modifică implementarea pentru eliminarea problemelor de mentenanță;
Înainte de a continua, ar trebui să lămuresc de ce, unde alţii văd ciclul red-green-refactor, eu văd patru paşi. Răspunsul simplu, algoritmic este că un ciclu constituie implicit şi un pas în orice proces: eu doar îl fac vizibil. Cum un articol nu poate cuprinde răspunsul mai interesant, mă mărginesc la un indiciu: vorbim despre test driven development, despre a croi o cale. Fără un pas în care să existe această componentă, nu putem vorbi despre TDD.
Pe lângă beneficiile Test First, această metodologie de a implementa ne oferă și:
Vizibilitate imediată asupra îmbunătățirilor aduse sistemului;
Posibilitatea de a măsura ciclul de implementare a unei cerințe;
Simplitatea celor patru pași ai TDD este înșelătoare. În spatele acestor reguli formulate banal se ascund procese (analiza de cod static sau rularea automată a testelor sunt doar două exemple). Rezultatele enumerate mai sus nu sunt ușor de obținut și depind de foarte multe cerinţe, dar şi de foarte mult exerciţiu. Dar doar pentru că e greu să ajungem la liman nu schimbă faptul că TDD facilitează un proces de îmbunătățire măsurabil.
După cum aminteam, spre deosebire de Test First, TDD trece de limitele unei simple practici de implementare a codului spre o tehnică de manufactură a soluțiilor software. Se pot aduce destule argumente că pentru programatori individuali, dar și în echipe mici, TDD este cea mai eficientă metodologie de implementare a soluțiilor software. Aşadar, TDD se aseamănă cu Gemba Kaizen pentru că ambele sunt procese de producţie. Mai mult de atât, ciclul TDD este aproape identic cu ciclul kaizen plan-do-check-act (PDCA).
Atunci când facem TDD, întotdeauna începem prin a planifica următoarea mutare, următorul test. În acest punct ne uităm la aspecte cum ar fi:
Implementarea unei cerințe funcționale a sistemului;
Acoperirea unui caz secundar sau a unui fir de execuție alternativ;
Descoperirea și tratarea unor defecte;
Ajustarea unui test existent;
Odată ce reperăm aceste lucruri, documentăm ceea ce am găsit prin scrierea unui test. Planificarea se încheie cu rularea tuturor testelor şi constatarea că noul nostru test eșuează.
Apoi acționăm făcând codul să treacă testul pe care l-am scris anterior. Ceea ce este important de remarcat este că faza planificării reduce această fază la una de execuție, înlăturând în bună măsură riscurile de a deveni prea creativi.
A treia fază a ciclului kaizen este cea a verificării. În cazul TDD această fază este cea mai ușor de realizat: se rulează din nou toate testele. O altă activitate mai subtilă, dar importantă în egală măsură este verificarea calității codului scris. Aici ne referim la verificarea îndeplinirii criteriilor formale de către soluția propusă (folosind unelte de analiză statică a codului, de exemplu). De asemenea, verificăm adeziunea codului la principii de design sănătoase (eliminarea duplicatelor literale și semantice, de exemplu). Aceste lucruri ne conferă posibilitatea de a măsura calitatea codului pe care-l livrăm în timp real.
În fine, ajungem la cea de-a patra și ultima fază - aceea în care luăm act de rezultatele verificării. Această fază este rezervată îmbunătățirii în sine, rezolvării problemelor găsite în verificare. În contextul TDD, această fază se reduce la a refactoriza codul. Pot exista şi situaţii mai puţin plăcute, cum ar fi aceea în care testul nostru trece, însă am introdus defecte semnalate de alte teste eşuate. În aceste cazuri reluăm ciclul PDCA pentru a remedia aceste aspecte.
Acest din urmă aspect reprezintă o diferență notabilă între ciclurile TDD și PDCA: pentru un ciclu TDD pot exista mai multe cicluri PDCA. A doua diferență notabilă este că în ciclul PDCA ultima fază presupune și îmbunătățiri ale procesului. Spre exemplu, aceste îmbunătățiri ar putea însemna introducerea sau ajustarea automatizărilor folosite în oricare din cele patru faze.
Astfel, dacă practicând TDD putem acționa previzibil și măsurabil asupra codului sursă care reprezintă produsul nostru, mergând spre kaizen influențăm şi procesele prin care producem acel cod. Această din urmă variantă produce cele mai bune rezultate. Notăm şi că tranziţia de la TDD la kaizen este una facilă datorită multelor similarităţi între cele două procese. Şi reciproca este valabilă, singura ajustare necesară fiind că un ciclu TDD presupune mai multe cicluri PDCA.
Concluzionând, TDD este un proces care facilitează kaizen în special la nivel individual. Practicând TDD, îmbunătăţirile devin măsurabile şi vizibile, iar timpul de livrare a codului în producţie este optimizabil. Adăugând practicii TDD şi elementele kaizen care-i lipsesc, această unealtă devine una dintre cele mai puternice pentru îmbunătăţirea performanţelor individuale în implementarea software.
de Daniel Tatar
de Ovidiu Mățan
de Diana Oniga
de Mihai Talpoș