De ce exista defecte in software?

Nu există niciun algoritm sau teoremă matematică practică și implementabilă care poate demonstra că implementarea unui program este corectă (bug-free). Este nevoie de testare ca proces pentru a evalua nivelul de corectitudine.

Procesul de dezvoltare al produselor IT este un proces creativ de rezolvare a problemelor și prin urmare există o probabilitate mare să apară erori (bug-uri)

Primul punct important de adresat este de ce există defecte? Și mai mult de a înțelege de ce vor exista defecte multă vreme de acum încolo.

Dezvoltarea de programe (incluzând aici testarea) este un proces creativ de rezolvare de probleme. Orice software/platformă dezvoltată înseamnă rezolvarea unor nevoi sau cerințe.

Deși există o parte cunoscută în acest proces (algoritmi, librării, design patterns) acestea sunt instrumente folosite de un dezvoltator pentru rezolvarea unei probleme. Dar fiecare proiect este unic în modul în care sunt descrise cerințele, în modul în care este gândită arhitectura și în modul în care arată în final produsul rezultat.

În cadrul acestui proces creativ există factori care creează bug-uri:

  1. Capacitatea umană limitată de a înțelege și lucra cu structuri complexe și avem acum produse din ce în ce mai complexe. Aici există riscuri mari de a crea sisteme cu multe probleme, unele structural profunde și altele mai superficiale.
  2. Comunicarea sau lipsa ei sau comunicarea deficitară. Aici bug-urile apar fie atunci când nu se transmite clar sau se transmite parțial informația. Fie se poate întâmpla ca cel care primește o informație să o interpreteze diferit de intenția celui care a comunicat-o. Deci în final sistemul creat este diferit de ce s-a dorit.
  3. Compromisul sau procesul decizional legat de alegerile construcției. Pentru că există un timp limitat/buget limitat, atunci procesul de dezvoltare are de luat decizii de implementare, de construcție. Începând de la ce limbaj de programare trebuie ales, ce bază de date, ce platformă până la modul în care se scrie codul sau se lansează. Acestea includ și decizii mai mici: dacă tratez cazurile extreme, cazurile mai puțin cunoscute cum este de exemplu tratarea unei secunde în plus odată la un număr de ani (exemplu de bug).

Dacă ne uităm doar la cele 3 puncte de mai sus putem observa că oricât de bună ar fi echipa de dezvoltare, ea nu poate acoperi toate cazurile și va exista tot timpul posibilitatea ca defectele să existe sau să nu ne poate asigura că s-a implementat corect ceea ce a fost cerut.
Cu siguranță a avea o echipă bine pregătită de dezvoltare scade anumite riscuri, dar nu le poate aduce la 0.

Verificarea exhaustivă este imposibilă

Dacă mai sus am explicat de ce există bug-uri, mai departe vom discuta despre imposibilitatea testarii exhaustive prin câteva exemple pragmatice.

De multe ori este posibil să avem impresia că putem verifica toate cazurile, însă această afirmație este incompletă. Mai corect este să spunem: „putem verifica toate cazurile la care ne-am gândit până acum”.

De exemplu: Să zicem că avem un sistem care are un singur input în care se poate scrie un număr întreg și afișează numărul respectiv + 1 când se apasă butonul „Rezultat”. Practic, dacă îi dai ca input valoarea 2 atunci afișează 3.

Testarea exhaustivă ar înseamna testarea tuturor numerelor întregi. Care este posibilă pentru că știm că pe calculator numărul de numere întregi este limitat (în multe limbaje de programare numărul maxim este 2,147,483,647 pentru INT 32 signed). Ar dura mult, dar poate fi posibil.

În plus ar înseamna să testăm și combinații de precondiții. Exemplu: să testăm dacă afișează corect răspunsul pentru numărul 10 când înainte de asta pusesem în sistem numărul 9 sau când pusesem numărul 8 …. Și aici numărul de posibilități este practic infinit. Matematic este o mulțime numărabilă, infinită.

Dar nu este suficient să testăm doar asta. Ar trebui să testăm și tot ce nu trebuie să meargă în acest software. Exemplu: să testăm că nu merge dacă scriem 11.3 sau dacă scriem valoarea „a” sau dacă scriem „a121a”. Și aici numărul de posibilități este practic și teoretic infinit, pentru că oricât de mult brainstorming am face nu este niciodată suficient. Oricând putem găsi un nou caz de testat.

Rezultă astfel că testarea exhaustivă este imposibilă.
Și mai rezultă că nu ne putem imagina mulțimea cazurilor posibile decât prin echivalență sau prin reducere la elemente comune. De exemplu putem să tratăm cazurile cu numere întregi, cazurile în care inputul conține litere, cazul în care inputul conține caractere neprintabile ș.a.m.d.

Deci efortul de a trata totul este imposibil.

Dacă testarea exhaustivă este imposibilă atunci nu putem găsi nicio demonstrație matematică sau strictă pentru corectitudinea unui program. Deci singura opțiunea pentru a avea un produs calitativ este un proces de evaluare a nivelului de corectitudine a software-ului pe o scală și potrivit unor metrici.

Și de aici derivă nevoia de testare, de a avea un rol, o persoană care se concentrează pe reducerea riscului ca ceva rău să se întâmple cu sistemul în timpul funcționării sale.

În concluzie, dezvoltatorul are o atitudine subiectivă asupra muncii sale. Este nevoie de un efort mare să poți privi obiectiv ce ai construit și să poți răspunde la întrebarea “ce cazuri mi-au scăpat?” sau “ce ar putea să meargă rău?” (vezi confirmation bias ca posibilă explicație a acestui subiectivism). Din acest motiv este nevoie fie de o altă persoană (testerul), fie de un task diferit (de a testa) ca să poți ieși din acest subiectivism al construcției vis-a-vis de posibile defecte ale acesteia.

Resurse suplimentare

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile necesare sunt marcate *