Era vineri, la câteva ore după release-ul în producție și cu câteva ore înainte de a se crea noul branch de release.. Toată echipa era deja obosită, am avut câteva luni pline din punct de vedere al funcționalităților lansate, release în producție săptămânal și o echipă de product care avea deja pe rol alte câteva feature-uri noi. Îmi scot căștile din urechi deoarece văd agitație în jurul meu. Cei doi colegi de ai mei își bat capul cu un defect pe care l-au găsit și vin către mine pentru sfaturi. A treia mea întrebare: se întâmplă și pe producție? Se uită unul la celălalt, își întorc scaunele rotative fiecare spre biroul lui, iar după un minut, am răspunsul: da. Colega mea se panichează în timp ce realizează că ea a dat QA sign off la release. Eu sunt calmă, nu e prima dată când văd aceasta întâmplându-se, și da, mi s-a întâmplat și mie.
Încerc să îi explic că scopul realist al testării nu este de a găsi toate defectele existente, ci de a asigura și de a demonstra încredere în calitatea produsului într-un timp scurt și cu efort limitat. Dar îi înțeleg reacția, deoarece atunci când suntem puși în situația de a fi considerați vinovați de un anume lucru, răspunsul sistemului nervos este de "luptă sau fugi"("flight or fight response"). Cea mai ușoară abordare ar fi să luăm vina în întregime asupra noastră (ceea ce nu ar fi corect), sau să transmitem vina asupra unei alte persoane (la fel de greșit): cineva a uitat să facă ceva, cineva a făcut greșit ceva, cineva ar fi trebuit să facă ceva diferit și tot așa mai departe. În timp ce scriam aceste rânduri, mi s-a confirmat încă odată cât de nepotrivită ar fi abordarea aceasta în contextul dat, așa e? Ce putem face să evităm reacțiile de acest gen? Putem încerca să ne construim câteva linii de apărare doar ale noastre, și putem începe prin a trece prin următoarele câteva exemple:
Nu o lua personal și păstrează-ți profesionalismul!
După legea lui Murphy, dacă este ceva ce poate să meargă prost, va merge prost, cel puțin odată. Dacă adăugăm un grup de indivizi la această ecuație, știind că suntem predispuși la erori, rezultatul probabil se va transpune în erori repetate și în vină aruncată din stânga în dreapta. De exemplu, responsabilitatea de a fixa un defect este de obicei a programatorului, dar putem spune că aceasta e același lucru cu a da vina pe el/ea pentru defectul ajuns în producție? E mai indicat să ne axăm pe "Cum putem evita repetarea aceleiași erori?" și nu neapărat cui îi aparține deplina responsabilitate.
Când defectul e găsit foarte aproape de release sau chiar în producție, proiectul este sub risc și nu echipa sau o anumită persoană. Așadar, oricare ar fi sursa bugului, - design, cod, implementare greșită, specificații greșite, testare incompletă - responsabilitatea ar trebui împărțită între toate persoanele care lucrează pe proiectul respectiv. În același timp, fiecare membru al echipei are o responsabilitate individuală de a lua măsurile necesare pentru ca asemenea erori să nu se repete, deoarece la urma urmei aceasta presupune jobul nostru - de a crea și livra software de calitate.
Privește-o ca pe o oportunitate!
Prima dată când am fost pusă într-o situație asemănătoare, ca din cauza testării, credeam eu, un bug să ajungă în producție, am petrecut probabil o zi întreagă încercând să îmi explic neatenția, să mi-o iert, să îmi promit că nu se va mai întâmpla și să mă gândesc la o modalitate în care aș putea să demonstrez tuturor implicați pe proiect ca eu de fapt sunt un tester bun și că nu mă definește o greșeală.
Ce puteam să fac în schimb? Puteam, împreună cu echipa, să ajungem la concluzia că sursa defectului în sine a fost comunicarea deficitară a tuturor celor implicați, să ajungem la metode mai eficiente de a discuta despre specificații și de a lămuri întrebări, și, începând de la următorul feature, să testăm dacă noua noastră abordare care ar trebui să ne ofere un grad de risc mai mic și un nivel de încredere mai mare în produsul nostru înainte de un release.
Așadar, principala noastră grijă nu ar trebui să fie strict faptul că a ajuns un bug în producție, în schimb, putem să facem doi pași în spate și să privim întreaga situație ca pe o oportunitate. Prin a arăta echipei ce am făcut și ce facem în mod constant pentru a îmbunătăți calitatea produsului și a muncii noastre, demonstrăm că suntem dornici să continuăm să facem aceasta și în viitor:
Identifică cauza bugului - lipsa testelor, a documentației, greșeli în specificații sau cerințe, lipsa timpului, și lista evident că nu este exhaustivă
Poți să execuți o verificare rapidă a zonelor din aplicație, unde ar putea să apară defecte similare.
Adaugă teste pentru scenariul care nu a fost acoperit. În acest mod ne asigurăm că bugurile similare vor fi identificate din timp.
Creează un raport de coverage pentru a identifica care sunt acele părți din aplicație care nu sunt suficient de testate din varii motive.
În legătură cu pasul acesta, consider că este destul de auto-explicativ. Ideea este să evităm să ascundem greșelile pe care le găsim într-un stadiu mai avansat al procesului de release sau chiar după ce buildul final e accesibil userilor din producție. Cu cât logăm mai repede sau mai devreme defectul, cu atât mai repede sau mai devreme putem, ca echipă, să ne gândim la soluții de termen scurt/lung, să fixăm defectul și să o livrăm utilizatorului final.
La urma urmei este de preferat un bug găsit în pre-producție decât în producție, un bug găsit în producție de QA decât de user, un bug de producție logat de către QA decât de departamentul de suport, un bug de producție logat decât unul ne-logat care la un anumit moment tot o să ajungă să fie raportat de cineva într-un fel sau altul.
Am mai menționat necesitatea acestei operații, dar de obicei responsabilitatea de a fixa un defect va cădea asupra developerului, dar, în calitate de QA, este responsabilitatea noastră să raportăm defectul într-un mod inteligibil și complet, să fim disponibili pentru ajutor pe parcursului întregului proces de fixare și testare.
În acest stadiu, echipa va trebui să se decidă asupra severității defectului și să continue sprintul actual (presupunând că lucrează în sprinturi) prin:
A pune la risc velocitatea echipei și a adăuga defectul la sprintul actual în vederea livrării fixului ca un patch.
A adăuga defectul în următorul sprint și a amâna livrarea fixului. Aceasta presupune asumarea unui risc prin a menține bugul în producție. Dar, de obicei, se alege această opțiune în cazul în care severitatea acestuia este una scăzută.
Se poate întâmpla să nu existe un business value pentru a face revert, dar există câteva metode prin care se poate diminua impactul negativ al defectului ajuns în producție. Poate fi o practică bună implementarea unei funcționalități în spatele unui flag sau al unui experiment, și aici mă refer la un A/B test. Astfel, la nevoie, dacă există o problemă legată de acea funcționalitate, și revertul nu e neapărat o opțiune, se poate apela la "oprirea" acestuia printr-o simplă schimbare de configurare sau oprirea unui experiment.
În cele mai multe echipe în care am lucrat, aceste ședințe de retrospectivă erau plănuite pentru ultima zi a sprint-ului și tind să fie cel mai convenient set up pentru a analiza dificultățile de orice tip de care s-a lovit echipa sau proiectul, și nu numai.
Evident, în cazul în care situația o cere, nu e foarte indicat să amânăm discuțiile până la retrospectivă, ci trebuie să o tratăm cu prioritatea care i se cuvine pentru a găsi o soluție de termen scurt, cel puțin. Mai apoi acestea pot fi re-adresate în cadrul retrospectivei și găsite soluții pe termen mediu spre lung.
Ideal ar fi ca fiecare membru al echipei să fie un participant activ în acel cadru și să contribuie într-un mod constructiv cu idei, propuneri și întrebări.
Am greșit și eu și toți din jurul meu vom mai greși. În schimb, în contextul de lucru, e de preferat de detectat ce anume din procesul pe care îl avem implementat, duce la repetarea greșelilor. Cum putem ajusta procesul încât să minimizăm frecvența erorilor? Aceasta e analiza cauzei fundamentale.
Clasică abordare este de a pune întrebarea "de ce" de cinci ori. Personal făceam aceasta când eram mică și încercăm să îl supăr pe fratele meu. De ce nu aș putea să fac același lucru, limitând întrebarea la un rezonabil cinci ori, în vederea găsirii unei soluții?
Găsirea cauzei fundamentale nu e "rocket science", probabil toți o aplicăm, fie că o facem într-un mod conștient sau nu. Așadar, nu voi insista asupra acestei tehnici mai mult decât este necesar. Ceea ce consider totuși că merită menționat, este riscul de a găsi prea multe "probleme" la început, de a ne apuca să le reparăm pe toate deodată și de a ajunge la concluzia că de fapt, toate problemele au o cauză care e în afară controlului nostru. Pe lângă aceasta, s-ar putea să și aplicăm excesiv această tehnică și să ajungem la un proces de lucru greoi, birocratic care să ne ia mai mult timp decât munca efectivă pe care o facem pe proiect. În cele din urmă, înainte de a alege această abordare, hai să ne întrebăm dacă problema noastră destul de repetitivă, încât să merite eventual îngreunarea procesului de lucru? Și apoi, un proces lipsit de erori nu e nici realizabil și nici de dorit.
Odată ajunși la o rezoluție, vom realiza că anumite situații pot fi îmbunătățite prin mici modificări ale obiceiurilor noastre proprii de lucru (cum testăm, cum scriem testele, cum comunicăm, cum ne împărțim timpul și taskurile, ș.a.m.d.). Dar de cele mai multe ori, pentru un impact mai mare, ajustările vor trebui făcute la nivel de echipă.
Citeam nu demult despre un seminar online, Software Testing Trends, unde se discuta despre anumite tehnici/skilluri noi care mi-au atras atenția. Partea interesantă în legătură cu ele a fost tocmai faptul că nu promiteau un release fără buguri, doar puterea informației: informația în legătură cu motivul pentru care s-au scăpat bugurile, și cum să minimizăm apariția și impactul acestora. Pe cealaltă parte, aceste tehnici veneau în completarea proceselor pe care le avem deja înrădăcinate, și ar trebui să ne ajute să raportăm informația mai rapid, mai devreme și într-un mod mai eficient, care la urmă urmei e jobul nostru de QA.
Imaginează-te în clasa a 5-a, cu o coală mare albă de hârtie și o cariocă. Îți scrii numele în exact mijlocul hârtiei și trasezi un cerc în jurul lui. După aceea desenezi multiple săgeți din direcția cercului, fiecare ajungând la câte un dreptunghi care conțin numele unor categorii: familie, prieteni, hobby-uri, animale de companie, ș.a.m.d. O vezi?
Probabil ți-ai amintit un moment similar din copilăria ta, și instant ai vizualizat cum ți-ai desenat propria harta a personalității, că așa se numeau. În schimb, îți amintești conținutul vreunui eseu pe care l-ai compus în același an? Dacă nu ai super puteri precum "Enhanced Memory" or "Panmnesia", răspunsul tău s-ar putea să fie nu.
Această tehnică este harta mentală, care ajută la vizualizarea procesului de gândire. Mă refer mai departe la ea, utilizând sintagma mind mapping.
Nu e absolut nimic extrem de nou sau revoluționar la această metodă, există chiar la noi în țară comunități care încurajează elevii la abordări asemănătoare pe parcursul formării lor.
Cum putem folosi mind maps la taskurile zilnice?
Test planning - e mult mai eficient decât un test plan de zeci de pagini, pe care nu îl citește atent în întregime nimeni, care nu e flexibil când vine vorba de ajustări și care își pierde aplicabilitatea foarte ușor. Cu mind maps putem face într-un mod foarte simplu distincția între ariile pe care vrem să ne axăm: taskuri, timpul alocat, tooluri folosite, riscuri, detalii despre environment. O rapidă vizualizare a mind mapului final ar trebui să ne ofere o perspectivă generală asupra scopului planului respectiv.
Test cases - putem crea ramuri diferite pentru fiecare user story/epic/feature și putem mai apoi adaugă idei/teste pentru fiecare funcționalitate disponibilă. Același raport se poate folosi pentru executarea testelor, oferind o perspectiva vizuală asupra testelor care au trecut sau au eșuat, oferind și posibilitatea adăugării atașamentelor. Se poate folosi mai apoi pentru a comunica rezultatele testării, adică în calitate de test report. Așadar, mind mapul nostru devine un document dinamic care se pliază perfect ciclului de testare. Rezultatul ar trebui să ofere vizibilitate și acoperire crescut.
Project dashboard - Progres, planificări, riscuri, probleme. Toate acestea puse în structura unui mind map ar trebui să ne ajute să vizualizăm " the bigger picture" și să înțelegem starea în care se află proiectul.
Meeting Minutes - Agendă, participanți, locul și ora, discuții, elemente de acțiune, documente, notițe, ș.a.m.d. Toate acestea pot fi adăugate într-un singur loc, și se poate colabora la menținerea acestora.
Analysis - Mind Mapurile sunt un mod foarte cool de a reține și de a ne aminti informații pe care le citim. Ajută la înțelegerea informației și este o metodă foarte ușoară de a învăța. Durează câteva minute să te uiți peste o grafica vizuală de tipul mind map, ca să redai informația pe care o ai deja prezentă în mintea ta.
Dacă nu există un template minimalist dar complet și eficient, artefactele de test tradiționale oferă o structură încărcată și nu e neapărat compatibilă cu abordarea agile a proiectelor la care lucrăm în prezent. Cu siguranță, metoda de mind mapping e mult mai utilă persoanelor cu stil perceptiv vizual, care procesează cel mai eficient informații în formă vizuală, adică imagini, video, grafice. Această tipologie este reprezentată de 65% din populație.
Zilnic facem față unei încărcături excesive de informații care ne reduce eficiența și eficacitatea. Așa apare lipsa de creativitate, începem să uităm lucruri, ne pierdem concentrarea și claritatea cu care ne raportăm la situații. Pe lângă că ne ajută să ne păstrăm organizați, utilizarea mind mapurilor stimulează creativitatea. Putem să facem să apară idei interesante și soluții originale, în timp ce desenăm cercuri, ramuri și săgeți.
Ciclul de testare necesită nenumărate documente, iar timpul pe care îl folosim pentru crearea și menținerea acestora ar putea fi folosit pentru testarea efectivă a aplicațiilor. Mind mapul poate cuprinde exact aceeași cantitate de informație, dar în mai puține cuvinte.
Procesele care funcționează pentru o anumită echipă depind extrem de mult de scopul și dinamica acelei echipe. Așadar, nu există o rețetă general aplicabilă, ci mai mult o direcție în ceea ce privește moduri de abordare și atitudinea persoanelor care construiesc respectiva colectivitate. De exemplu, există o echipă care lucrează la software-ul folosit de către NASA, a cărei proces își bazează rădăcinile în rivalitate.
"The group's most important creation îs not the perfect software they write — it's the process they invented that writes the perfect software."
Această echipă are subgrupuri, cele importante fiind programatorii și cei care verifică munca programatorilor. Aceste subgrupuri lucrează după procese foarte diferite și plan de management distinct, dar interacționează foarte mult pe parcursul întregului proces. Programatorii ar trebui să livreze cod fără nicio greșeală, iar verificatorii ar trebui să testeze scenarii care dezvăluie cât mai multe defecte. De obicei, se ajunge la un concurs între cele două echipe deoarece programatorii vor să își găsească propriile defecte înainte să le găsească rivalii lor. Rezultatul acestui proces este găsirea a 99.9% dintre defecte înainte că software-ul să ajungă la NASA, din care 85% sunt găsite înainte să ajungă la QA. Poți citi mai multe despre acest proces.
În concluzie, procesele ar trebui să fie contextualizate și ajustate până când se ajunge la o variantă cât mai apropiată de dinamica proiectului și a echipei, dar contribuția individuală e cea care stă la bazele evoluției unei colaborări sănătoase.
de Ovidiu Mățan
de Ovidiu Mățan