5 principii esentiale in testarea automata

1. Setup & teardown

Mecanismul de setup si teardown se refera la crearea datelor de test in metode specifice de pre-run, iar apoi stergerea acestor date sau revenirea la valorile initiale in cazul in care au fost date doar modificate, in metode de post-run. Astfel, inaintea executiei unui test automat, pregatim datele de teste in metode de pre-run(setup), care pot insemna, diverse apelari de RestApi sau interogari si operatiuni in bazele de date ale aplicatiei sau chiar si generarea de date de test aleatorii folosind functii special create pentru aceasta.
Apoi, dupa executia test case-ului, intra in scena metoda de post-run(teardown), care presupune ca toate datele de test care au fost create si folosite in test case (date create in setup) sa fie sterse sau modificate la valorile lor initiale. Atentie, metodele de post-run trebuie sa se execute indiferent de statusul test case-ului, daca a fost Pass sau Fail.
O greseala comuna in testarea autoamata este nerularea metodelor de teardown in cazul in care test case-ul este Fail. In acest caz, tot ce a fost creat si modificat in setup, va ramane, putand astfel sa cauzeze un rezultat neasteptat la urmatoarele rulari.

2. Testele trebuie sa fie independente

Fiecare test case automat ar trebui sa poata rula independent fara a depinde de alt test case-uri. Aceasta dependenta se refera atat la datele de test, cat si la locul de unde incepe test case-ul sa se execute in aplicatie. De foarte multe ori am observat situatii in care se incepe automatizarea unui test case din locul unde test case-ul precendent a lasat aplicatia. De exemplu: daca aplicatia noastra are 10 ecrane si noi avem 10 test case-uri pentru fiecare ecran, daca test case-ul 5 incepe de unde a terminat test case-ul 4, este gresit. Aceasta presupune dependenta fata de testul precedent. Daca test case-ul 4 esueaza in momentul executiei, niciun alt test care urmeaza si care depinde de el nu va putea sa se execute cu succes.
Este valabil si in cazul datelor de test. Daca un test are nevoie de anumite date care ar trebui create de catre un alt test case, este deasemenea gresit. Datele de test pentru teste ar trebui intodeauna create folosind un mecanism de setup & teardown, asa cum a fost  descris la punctul 1.
Dependenta intre teste, omoara testarea paralela.

3. Introducerea unui mecanism de retry(re-rulare a testului)

De multe ori in testarea automata nu putem controla tot mediul de testare. Spre exemplu, nu avem niciun control asupra timpului in care un browser incarca aplicatia sau un API raspunde in urma unui apel HTTP. Acestea pot depinde de foarte multi factori care pot tine de la incarcarea masinii pe care executam testele, pana la latenta vitezei internetului in acel moment. Cum ne afecteaza lucrul acesta executia testelor automate? Prin faptul ca ne poate introduce rezultate neasteptate in momentul executiei. O greseala comuna este aceaa de a adauga timpi de asteptare de fiecare data cand intalnim astfel de comportamente. Este o abordare gresita pentru ca aceste asteptari nu fac nimic altceva decat sa adauge ceea ce numim timp mort in executie. Timpul mort este reprezentat de timpul in care suita de teste asteapta, de multe ori fara sa fie nevoie de aceste asteptari. Pe termen mediu si lung, privit macro (la nivel de suita de teste, nu de test case), acele cateva secunde pe care le adaugam se vor transforma in minute bune, cand le vom aduna din toate test case-urile. Nu este optim sa avem o suita de teste care sa se execute in zeci de minute sau poate chiar ore. Aici intervin mecanismele de retry, unde, atunci avem nevoie de o anumita conditie pentru a trece mai departe, in loc sa asteptam ca acea conditie sa se indepliuneasca dupa un anumit timp, introducem un mecanism de retry al pasului respectiv si incercam din nou in loc sa asteptam.

4. Executia paralela

Executia paralela ne ajuta sa micsoram timpul de rulare a testelor. Pentru orice companie care dezvolta software, “time to market” este esential si se traduce de cele mai multe ori in veniturile pe care compania respectiva este capabila sa le genereze. Time to market se refera la capacitatea organizatiei de a a livra un produs finit catre publicul tinta. Masoara timpul de la concept, pana in punctul in care utilizatorul final poate folosi produsul respectiv. Cu cat acest timp este mai mic, cu atat compania isi creste sansele de succes. In cazul in care timpul mare, exista riscul ca utilizatorii finali sa primeasca acealsi produs de la o companie concurenta, ceea ce va scadea sansele de succes. In acest context, cand totul se reduce la viteza de livrare,  o suita de teste automate care ofera un feedback dupa o executie care poate dura ore (pentru fiecare instalare in productie a aplicatiei) nu este cea mai buna idee. In aceste situatii, din pacate, exista riscul de a se sari peste executia testelor, pentru ca dureaza prea mult.

Dar ce facem daca testele sunt pur si simplu foarte multe si dureaza foarte mult? Solutia este: testarea in paralel. In primul rand, ca sa putem testa in paralel, toate principiile de mai sus trebuie sa fie implementate in suita noastra de teste. Daca testele sunt independente si nu depind unele de altele sau de acelasi seturi ale datelor de test, atunci, imaginati-va o suita de teste care in mod normal se executa in 4 ore, ca poate fi impartita pe 4 fire de executie separate (chiar si pe 4 masini diferite) si vor rula in doar 1 ora. Daca adaugam alte 4, vor rula in 30 de minute. O astfel de abordare ne ajuta sa economisim timp. Alt avantaj este si faptul ca reducand timpul de executie total, putem rula suita la fiecare schimbare de cod pe care programatorii o fac, astfel crescand increderea in calitatea software-ului livrat.

5. Executia in CI/CD

CI (Continuous Integration)/CD(Continuous deployment) sunt practici din dezvoltarea software care presupun o integrare si instalare continua in productie a schimbarilor aduse in programul software. Ele ne ajuta sa atingem acel time to market de care  aminteam mai sus. Ca aceste lucruri sa se poata intampla fara incidente majore, software-ul trebuie sa fie testat. Insa nu putem atinge acea viteza si integrare continua daca trebuie sa ne oprim tot timpul sa asteptam ore sau zile testarea aplicatiei. Testarea trebuie sa se intample rapid, continuu si fara sa aduca timpi de asteptare mari. Am intalnit multe situatii in care se scriu teste automate si se executa de pe calculatorele individuale. Altfel spus, sunt teste automate executate manual. Este o abordare gresita! Testele automate trebuie sa fie executate in mod automat, declansate de schimbarile in cod pe care le fac programatorii aplicatiei si sa actioneze ca o poarta de siguranta. Daca un programator schimba ceva in cod, se vor declansa testele automate, iar daca un test pica, atunci schimbarea facuta de programator nu trebuie sa treaca mai departe pana nu analizam daca a cauzat testul care a fost fail. Acesta este unul din scopurile testelor automate: sa te aiguri ca ceea ce ai implementat nu strica ceea ce exista deja in aplicatie.

In concluzie, nu este suficient sa stim doar sintaxa unui limbaj de programare si metodele unei librarii pentru a scrie teste automate.

O suita de teste construita corect trebuie sa se bazeze inca de la inceput pe principii corecte, pe un  mod corect de a structura codul scris, astfel incat sa putem avea atat stabilitate, perfomanta, scalabilitate pentru noi teste , dar si un nivel de mententanta cat mai redus.