Din carneţelul de notiţe al unui software tester. Partea 1: ce-i testarea?

Autorul are o “vastă experienţă” de nici 3 ani de zile în domeniu.
Asta-i viaţa, dacă nimeni altcineva cu mai multă autoritate
nu se apucă să scrie .. scriu pufanii.

~*~

Merg prin oraş, interacţionez cu diverşi oameni. Taximetrişti. Chelneri. Necunoscuţi.

Ei mă întreabă unde lucrez. Iar eu le spun. Unde lucrez. Şi anume, că-s de meserie “testator de programe“, sau “software tester” în engleză în original. Iar oamenii se uită la mine cu mirare, şi mă întreabă mai timid sau mai curajos .. dom’le, dar ce-i testarea aia? Ce FACI mai exact?

Păi, hai să lămurim misterul, zic.

~*~

Pentru puţin context: testarea e vastă. Oamenii scriu software, adică programe pentru calculator. Şi nu doar pentru calculator. Miniaturizarea tehnologiei face ca astăzi să avem un calculator în buzunar (smartphone), câteva zeci de calculatoare în maşină (ECU, senzori), diverse calculatoare în maşinăriile din spitale, nu-ştiu-câte maşini de calcul într-un avion, şamd.

Toate maşinăriile astea programabile pot avea erori de funcţionare. Un programator prost poate face ca o maşinărie de iradiat pacienţii cu cancer să primească de 100x mai multă radiaţie decât e cazul (Therac 25). Chestii de-astea unthinkable, de neimaginat.

Toate domeniile mai serioase au nevoie de testare: şi cel bancar, şi cel medical, şi avionica, şi webul, şi dezvoltatorii de jocuri. Toţi. Fără excepţie. Desigur, nu toţi cu aceeaşi rigoare. În domeniul medical, dacă nu testezi rişti să omori oameni. Pe web, dacă nu testezi rişti să pierzi datele bancare a milioane de oameni. Chiar şi în domeniile “sigure”, gen jocurile, necesită testare pentru a nu scoate un căcat pe piaţă — lumea nu cumpără căcaturi, compania pierde milioanele de dolari investite, şamd.

Eu unul am făcut testare în automotive, chestie de reţinut ca un mic bias. Pot vorbi despre toate domeniile, dar n-o fac din postura de insider.

~*~

Pentru a înţelege testarea, trebuie să spunem câteva cuvinte despre programare. Ciclul de viaţă al unui program începe la nivel formal, când cineva emite nişte cerinţe — “băi, vreau un program care să facă ASTA şi AIA şi ouă prăjite pe lângă”. Fie vine un client al companiei şi cere ceva, fie însăşi compania îşi propune să creeze ceva nou; dar e clar că acel ceva se bazează pe nişte cerinţe. Care glăsuiesc lămurit despre design, despre ce face produsul, despre cum face ceea ce face.

Pe baza acestor instrucţiuni se creează chestii. Pentru web, pe baza cerinţelor faci un sait şi-i alegi găzduire. Pentru automotive, pe baza cerinţelor alegi nişte hardware, pe care apoi te gândeşti ce program scrii, cum comunică echipamentul ăsta cu exteriorul şamd.

~*~

Testarea programelor începe prin a verifica cerinţele: băi, le putem citi şi înţelege? Au sens? E clar din cerinţe cam ce a vrut clientul? Este totul clar, sau există ambiguităţi în exprimare? Arhitectura sistemului pare să corespundă cu ce zice clientul că doreşte să obţină? Dacă răspunsul este negativ la vreo porţiune din cerinţe, domeniul afectat de ambiguitate se marchează ca ne-testabil.

De ce zic că lucrurile încep de la cerinţe? Păi, testarea este practic o comparaţie între ceva şi altceva.

Nu poţi testa un scaun prin el însuşi. Îl testezi comparându-l cu cerinţele mai implicite sau mai explicite: E solid? E vopsit fain? E făcut din lemn de fag? Rezistă dacă se pune un tip de 200 de kilograme cu picioare pe el?

Produsul finit, software-ul, este acel “ceva” din comparaţie. Cerinţele sunt altceva-ul.

~*~

Lista metodelor prin care poţi testa un program este o lungă şi destul de seacă pentru oamenii nontehnici. Totuşi, câteva vorbe se pot spune despre “ce” şi “cum”.

În primul rând, se poate verifica softul, pus gol pe masă. White-box testing în zice, adică metoda “cutie transparentă”. Ne uităm la codul-sursă şi vedem cum funcţionează el. Avem o instrucţiune de decizie? Păi verificăm să se poată executa şi instrucţiunile pentru cazul că decizia s-a luat, şi pentru cazul că decizia nu s-a luat.

Se poate verifica şi invers, pe principiul că softul este o cutie neagră, “black box testing”. Nu ne interesează măţăraia din spatele cutiei, ci cum reacţionează cutia. Mi se dă manualul de utilizare, practic vorbind, iar eu testez ce pot face. Funcţionalitate cu funcţionalitate. Zice în manual că există un formular din care pot alege data naşterii? Foarte bine, trimit forţat serverului că m-am născut pe 1 Ianuarie 1830. Ştie cu de-astea?

~*~

Se mai testează limitele funcţionale. Dacă un server web trebuie să poată deservi 10000 de utilizatori simultan, se va supune unui test de încărcare cu 15000 de conexiuni. Dacă o bază de date trebuie să suporte 1000000 de scrieri pe zi (un milion, da) — se vor scrie 2000000 de seturi de informaţii. Dacă softul de pe un senzor se execută la fiecare 0,01s (la fiecare 10ms deci) — se ia osciloscopul şi se verifică într-adevăr că procesorul chiar execută acel soft.

Se testează precizia. Dacă un senzor de pus pe maşină promite că poate măsura temperatura cu precizie de 0.1 grade Celsius, se ia şi se bagă într-un cuptor împreună cu un termometru real, şi se compară rezultatele. Face într-adevăr senzorul diferenţa dintre 60,1 şi 60,2 grade? Dar între 102,5 şi 102,6 grade? Rezistă până la 130 de grade, cum promite fabricantul? Nu începe să dea rateuri la temperaturi extreme?

Se testează validitatea algoritmilor. Dacă vrem să citim date de la un convertor ADC(i), aplicând un filtru trece-jos, vom servi convertorul cu date din întregul spectru aplicabil, şi vor verifica că într-adevăr filtrul a eliminat ce era de eliminat. Se ia un set de date culese din realitate, se dau algoritmului, şi se compară rezultatul cu unul ideal.

Se alege CE se testează în mod dinamic. Erorile nu vin niciodată singure. Dacă o funcţionalitate calculează ceva greşit, altele vor consuma date greşite. O axiomă bine-cunoscută zice că 20% din codul-sursă poate genera până la 80% din erorile descoperite. Dacă la începutul unui proiect plănuim să alocăm timp egal tuturor funcţionalităţilor, odată descoperite problemele mai mari e clar că se poate face o re-prioritizare. După care se dau la reparat erorile descoperite, programatorii creează un nou release de software, şi se reia testarea.

~*~

Să fie clar: testarea nu face altceva decât să identifice erori. Ea nu poate promite, însă, că toate erorile au fost descoperite. Poate .. doar dacă vorbim despre un soft trivial, care rulează pe ceva hardware trivial, unde absolut toate variaţiile posibile de date de intrare sunt testabile programatic.

Sau, alternativ, dacă vorbim de un soft care a fost folosit atât de extensiv încât toate erorile semnificative au fost descoperite. Genul softurilor built-in în Linux, care prin rafinare ajung aproape de perfecţiune. E totuşi pernicioasă abordarea asta: eroarea numită “Heartbleed” a supravieţuit în codul OpenSSL timp de vreo 2 ani înainte să fie descoperită. Orice unealtă care primeşte petice (updates) de orice fel poate deveni brusc mai vulnerabilă decât era înainte. Orice modificare a codului-sursă, chiar dacă e făcută pentru a petici ceva, poate introduce efecte colaterale pe care nu le observă nimeni.

Scopul testării este strict să dea o patină de credibilitate softului. Cu alte cuvinte, “noi am testat în limitele de timp şi de banii pe care ni i-aţi dat”. Dacă echipa de testori are la dispoziţie suficient timp, va face treabă decentă. Dacă-s minţi strălucite, vor găsi exact turma de erori logice care pot provoca cele mai multe erori. Dacă nu-s bani .. asta e, mai testează şi utilizatorul. Foarte validă abordare în testarea jocurilor, unde versiunea “beta” înseamnă că jucătorii fac bug reports, iar dezvoltatorii fug cu extinctorul de la un bug la altul(ii). Abordarea NU e valabilă în avionică :D

~*~

În articolul următor poate reuşesc să scriu de fapt partea de “jurnal” a articolui ăsta.

----------
  1. Analog-to-Digital Converter. []
  2. Mă rog, în accepţiunea modernă. Pe vremea mea nu era aşa. []
----------
Taxi Radio, o poveste "de cartier"
Eternele reclame

Comments 3

  • Amuzant e atunci cand vrei sa-ti faci cont pe un site, ti se cere data nasterii si ti se deschide un widget tip “calendar”. Iti alegi respectiva data si ramai interzis la o eroare “Invalid date format”. Dupa 2 minute de scarpinat in cap iti dai seama ca selectarea unei date din widget produce un string de tipul ZZ/LL/AAAA, iar validatorul aceluiasi camp se asteapta la un string de tipul LL/ZZ/AAAA. Deci daca ziua nasterii tale e mai mica sau egala cu 12, nici n-ai remarca un asemenea bug ^_^

  • Testarea implică și sugestii de îmbunătățire? De exemplu, produsul cutare respectă cerințele, dar testându-l observi că cerințele sunt tâmpe sau clientul nu s-a gândit la o chestie (iar utilizatorul se va lovi de acel design defectuos sau parțial). De exemplu, ca să completeze un formular, trebuie să dea click pe Next Page de 10 ori, când ar fi fost mult mai simplu și frumos să fie totul pe o pagină.

  • Depinde de domeniu. Eu sunt pe automotive, unde mai rar vezi sugestii de imbunatatire, fiindca cine iti scrie cerintele este tot un om tehnic. Clientul isi trimite inginerii la discutii, firma isi trimite arhitectii de sistem si alte oameni tehnici, rezulta un set de cerinte care-i destul de aproape de realitate. Se mai schimba chestii micute.

    Altfel insa, pe web lucrurile sunt foarte fluide din cate stiu. Proiectul isi schimba infatisarea complet de cateva ori de-a lungul dezvoltarii, *si* in urma feedbackului de la testare.