Testarea structurală reprezintă o abordare a proiectării cazurilor de test prin care testele sunt derivate din cunoașterea structurii și implementării programului. Această abordare este uneori denumită “white-box”, “glass-box” sau “clear-box” pentru a o deosebi de testarea “black-box”.
Întelegerea algoritmului utilizat într-o componentă poate ajuta în identificarea altor partiții și cazuri de test. Pentru ilustrarea acestui concept, se va implementa o specificație de rutină de căutare sub forma rutinei de căutare binară. Secvența este implementată ca un vector ordonat. Prin examinarea codului rutinei de căutare, se observă că implică împărțirea spațiului de căutare în trei părți. Fiecare din aceste părți compun o partiție de echivalență ( Figura 8 ) . Se proiectează apoi cazuri de test în care cheia se află la limitele fiecărei partiții. [2.3]
Numărul de căi printr-un program este de obicei proporțional cu dimensiunea acestuia. Pe măsură ce modulele sunt integrate în sistem, devine infezabil să fie folosite tehnicile de testare structurală. Tehnicile de testare de cale sunt, de aceea, utilizate preponderent pentru testarea de componente. Testarea de cale nu verifică toate combinațiile posibile alte tuturor căilor prin program. Pentru orice altă componentă, în afara celor triviale, fără bucle, acesta este un obiectiv imposibil. Există un număr infinit de combinații de căi posibile într-un program cu bucle. Chiar și atunci când toate instrucțiunile programului au fost executate cel puțin o dată, defecte de program încă pot apărea atunci când anumite căi sunt combinate. Punctul de start pentru testarea de cale este un graf al fluxului de program. [2.4] Acesta este un schelet al tuturor căilor prin program și constă din noduri ce reprezintă decizii și arce ce indică fluxul de control. Graful fluxului este construit prin înlocuirea instrucțiunilor de control ale programului cu diagrame echivalente. Dacă nu există instrucțiuni de tip “goto” într-un program, derivarea grafului este un proces simplu. Fiecare ramură a unei instrucțiuni condiționale ( if-then-else sau case ) este ilustrată ca o cale separată. O săgeată înapoi către nodul condițional indică o buclă. În Fig. 10 este ilustrat graful pentru căutarea binară. Fiecare instrucțiune este un nod separat și numărul nodului corespunde cu numărul liniei din program. [2.1]
Obiectivul testării de cale este asigurarea faptului că fiecare cale independentă prin program este executată cel puțin o dată. O cale independentă prin program este aceea care traversează cel puțin un arc nou in graful fluxului. În termeni de program, acest lucru implică solicitarea uneia sau mai multora condiții noi. Atât ramurile adevărate cât și cele false ale tuturor condițiilor trebuie executate.
În graful fluxului pentru căutarea binară din Fig. 10, fiecare nod reprezintă o linie din program cu o instrucțiune executabilă. Urmărind fluxul, se pot determina căile prin graf:
Dacă toate aceste căi sunt executate, se poate cunoaște cu certitudine că fiecare instrucțiune din metodă a fost executată cel puțin o data și fiecare ramură a fost verificată pe cazurile adevărat și fals.
Se poate găsi numărul de căi independente într-un program prin calculul complexității ciclomatice ( McCabe, 1976 ) al grafului de flux corespunzător programului. Pentru programele fără instrucțiuni de tip “goto”, valoarea complexității ciclomatice este numărul de condiții din program + 1. O condiție simplă este expresia logică fără conectori de tip “și” și “sau”. Dacă programul include condiții compuse, care sunt expresii logice ce au conectori “și” și “sau” în componență, atunci se numără condițiile simple din condițiile compuse atunci când se calculează complexitatea. [2.1]
De aceea, dacă sunt șase instrucțiuni de tip if și o buclă while și toate expresiile condiționale sunt simple, complexitatea ciclomatică este 8. Dacă o expresie condițională este compusă, ca de exemplu “if A atunci B sau C”, atunci se numără aceste trei condiții simple. Complexitatea ciclomatică este astfel 10. Pentru căutarea binară, complexitatea ciclomatică este 4, deoarece sunt trei expresii condiționale simple la liniile 5, 7 și 11.
După ce se determină numărul de căi independente prin cod calculând complexitatea ciclomatică, se proiectează cazurile de test astfel încât să execute toate aceste căi. Numărul minim de cazuri de test necesar pentru a testa toate căile programului este egal cu complexitatea ciclomatică.
Proiectarea cazurilor de test este simplă în cazul căutării binare, însă, atunci când programele au o structură ramificată complexă, poate fi dificil să se determine cum va fi procesat un caz de test particular. În aceste cazuri, un analizor dinamic de program poate fi folosit pentru a determina profilul de execuție al programului. [2.1]
Analizoarele dinamice de program sunt instrumente de testare care funcționează în conjuncție cu compilatoarele. În timpul compilării, aceste analizoare adaugă instrucțiuni suplimentare la codul generat. Acestea numără de câte ori fiecare instrucțiune de program a fost executată. Dupa ce programul a fost rulat, un profil de execuție poate fi listat. Acesta indică părțile din program care au fost sau nu executate folosind cazuri de test particulare. Profilul de execuție dezvăluie astfel secțiuni de program care au rămas netestate. [2.3]
Testarea reprezintă un proces costisitor și laborios al dezvoltării software. Astfel, instrumentele de testare au fost printre primele instrumente software dezvoltate. Acestea oferă acum o gamă diversă de facilități și pot reduce semnificativ costurile de testare.
Un astfel de framework de testare este JUnit, folosit pentru testare de regresie. Acesta este un set de clase Java pe care utilizatorul le extinde pentru a crea un mediu de testare automatizat. Fiecare test individual este implementat ca un obiect și un executor de teste le rulează pe toate. Testele în sine trebuie scrise în așa fel încât să indice dacă sistemul s-a comportat conform așteptărilor. [2.4]
Un workbench de testare reprezintă un set de instrumente integrate pentru a susține procesul de testare. În plus față de framework-urile care suportă execuția automată a testelor, un workbench poate include instrumente pentru a simula alte părți ale sistemului și pentru a genera date de test. Printre instrumentele care pot fi incluse, sunt menționate [2.1]:
Când sunt utilizate pentru sisteme de dimensiuni mari, instrumentele trebuie configurate și adaptate pentru sistemul particular care este testat. De exemplu: [2.2]
6) Concluzii [2.2]
-
Testarea poate doar indica prezența defectelor într-un program, însă nu poate demonstra ca au fost eliminate toate defectele.
-
Testarea de componente este responsabilitatea dezvoltatorului sistemului. O echipă separată de testare realizează în general testarea sistemului.
-
Testarea de integrare reprezintă activitatea în care se testează componentele integrate și are rolul de a identifica defecte. Testarea funcțională are rolul de a testa versiunile produsului software și de a valida faptul că acestea întrunesc specificațiile.
-
Atunci când se testează sisteme, trebuie încercat să se “strice” sistemul prin alegerea tipurilor de cazuri de test care au fost eficiente în descoperirea de defecte în alte sisteme.
-
Testarea interfețelor are rolul de a descoperi defecte în interfețele componentelor compuse. Defectele de interfață pot apărea din cauza erorilor făcute în analiza specificațiilor, neînțelegerea specificațiilor, erori în cadrul specificațiilor în sine sau presupuneri de sincronizare greșite.
-
Partiționarea de echivalență reprezintă un mod de a deriva cazuri de test. Aceasta depinde de găsirea de partiții ale intrărilor și ieșirilor și solicitarea programului cu valori din cadrul acestor partiții. Adeseori, valoarea care are cea mai mare probabilitate de a duce la un test de succes este cea de la limitele unei partiții.
-
Testarea structurală se bazează pe analizarea unui program pentru a determina căile prin acesta și utilizarea acestei analize pentru selecția cazurilor de test.
-
Automatizarea testării reduce costurile testării prin augmentarea procesului de testare cu o gamă variată de instrumente software.
Capitolul 3: Verificare şi validare de programe
Testarea unui program este cel mai comun mod de a verifica dacă sunt îndeplinite specificațiile și face ce vrea clientul. Cu toate acestea, testarea este doar una dintr-o serie de tehnici de verificare și validare. Unele dintre aceste tehnici, cum ar inspecțiile de program, au fost folosite de aproape treizeci de ani, dar încă nu au devenit parte din ingineria software.[3.1]
Obiective:
-diferenta dintre verificare software si validare software
- introducere in inspectiile de program ca metoda de a descoperi defecte de program
- intelegerea modului de analiza statica automata si modul in care este folosit in verificare si validare
- cum este folosita verificarea statica in procesul de dezvoltare
În timpul și după procesul de implementare, programul în curs de dezvoltare trebuie să fie verificat pentru a se asigura că acesta îndeplinește caietul de sarcini aferent și oferă funcționalitatea așteptata de oamenii care platesc software-ul. Verificarea și validarea reprezinta numele dat la aceste procese de control și analiză. [3.1]
Verificarea are loc în fiecare etapă a procesului software.Verificarea și validarea nu sunt același lucru, deși sunt adesea confundate.
Boehm (Boehm, 1979) și-a exprimat succint diferența dintre ele:
• "Validarea: Am construit potrivit produsul?"
• "Verificare: Am construit produsul potrivit?"
Aceste definiții ne spun că rolul de verificare presupune controlul că software-ul este conform cu specificația sa. Trebuie verificat că îndeplinește specificatiile sale funcționale și non-funcționale. Validarea, totuși, este un proces mai general. Scopul validarii este de a se asigura că sistemul software îndeplinește așteptările clientului. [3.1]
Scopul final al procesului de verificare și de validare este de a stabili încrederea că sistemul software-ul este "potrivit pentru scopul care a fost proiectat". Nivelul de încredere necesar depinde de scopul sistemului, așteptările utilizatorilor sistemului și mediul de comercializare al acestuia:
-
Funcția Software-ului. Nivelul de încredere necesar depinde de scopul software-ului. De exemplu, nivelul de încredere necesar pentru software-ul care este utilizat pentru a controla un sistem critic pentru siguranță este mult mai mare decât cea necesară pentru un sistem software prototip care a fost dezvoltat pentru a demonstra unele idei noi.
2. Așteptările utilizatorilor. Este o reflecție tristă asupra industriei software in care mulți utilizatori au așteptări scăzute asupra software-ului lor și nu sunt surprinsi când acesta da erori în timpul utilizarii. Ei sunt dispuși să accepte aceste erori de sistem atunci când beneficiile utilizarii sunt mai mari decât dezavantajele. Cu toate acestea, toleranța de erori de sistem a scăzut începând cu anii 1990. Aceasta este acum mai puțin acceptabila pentru a furniza sisteme fiabile, astfel încât companiile de software trebuie să depună eforturi suplimentare pentru verificarea și validare.
3. Mediul de marketing . Atunci când un sistem este comercializat, vânzătorii de sistem trebuie să ia în considerare programele concurente, prețul pe care acești clienți sunt dispuși să il plateasca pentru un sistem. In cazul in care o firma are puțini concurenți, aceasta poate decide să lanseze un program inainte de a fi pe deplin testat și depanat pentru că vor să fie primul si sa apara cat mai repede pe piață. În cazul în care clienții nu sunt dispuși să plătească prețuri ridicate pentru software-ul respectiv, ei pot fi dispusi să tolereze mai multe defecte ale acestuia. Toți acești factori trebuie să fie luati în considerare atunci când se decide cât de mult efort ar trebui să fie depus pe procesul de verificare si validare. [3.1]
În cadrul procesului de validare si verificare, există două abordări complementare pentru controlul și analiza sistemului:
-
Inspecții software : analizeaza și verifica reprezentările sistemului cum ar fi documentul cu cerințele, diagramele de design și codul sursa al programului. Se pot folosi inspecții în toate etapele procesului. Inspecțiile pot fi completate de unele analize automate ale textului sursă al unui sistem. Inspecțiile și analizele automate de software sunt tehnici statice de validare si verificare.
-
Testarea Software-ului : implică executia implementarii software-ului de test cu date. Se examineaza rezultatele software-ului și comportamentul său operațional la verificari dacă funcționează conform necesităților. Testarea este o tehnică dinamica de verificare și validare.
Figura 1. Validarea si verificarea statica si dinamica [3.1]
Aceasta figura arată că inspecțiile de software și de testare joacă roluri complementare în procesul software. Săgețile indică etapele procesului în care tehnicile pot fi utilizate. Prin urmare, se pot utiliza inspecțiile software la toate etapele procesului software. Așa cum am discutat, cerințele și comentariile de proiectare sunt principalele tehnici utilizate pentru detectarea erorilor din caietul de sarcini și design. Se poate testa doar un sistem atunci când un prototip sau o versiune executabila a
programului este disponibila. Un avantaj de dezvoltare este disponibilitatea unei versiuni testabile a sistemului într-un stadiu destul de devreme în procesul de dezvoltare. [3.2]
Tehnicile de control includ inspecții de program, analiză automata de cod sursă și verificarea formală. Cu toate acestea, tehnicile statice pot verifica numai corespondența între un program și specificatiile sale; nu pot demonsta că software-ul este operațional. De asemenea, nu se pot utiliza tehnici statice pentru a verifica proprietățile emergente ale software-ului, cum ar fi performanța și fiabilitate. [3.2]
Testarea presupune exercitarea programul folosind datele, cum ar fi datele reale prelucrate de program. Defectele de program sau inadvertențele se vor descoperi prin examinarea rezultatelor programului și se caută anomalii.
Există două tipuri distincte de testare care pot fi utilizate la diferite etape ale procesului software:
1.Testarea de validare este destinata să demonstreze că software-ul este ceea ce clientul vrea - că îndeplinește cerințele sale. Ca parte a testului de validare, s-ar putea folosi testarea statistică pentru a testa performanțele programului și fiabilitatea, precum și a verifica cum reactioneaza în condiții de funcționare.
2. Testarea defectelor este destinata să dezvăluie defectele din sistem mai repede decât prin simularea utilizarii operaționale. Scopul testării defectelor este de a găsi neconcordanțe între un program și specificatiile sale. [3.2]
Desigur, nu există nicio limită de greutate și rapiditate între aceste abordări de testare. Procesele de validare, verificare și depanare sunt în mod normal intercalate. Pe măsură ce se descopera defecte în programul care se testeaza, va trebui modificat programul pentru a corecta aceste defecte. Cu toate acestea, testarea (sau, mai general, verificarea și validarea) și depanarea au obiective diferite:
1. procesele de verificare și validare sunt destinate pentru a stabili existența defectelor unui sistem software.
2. depanarea este un proces care localizează și corectează aceste defecte.
Figura 2. Procesul de depanare[3.2]
După ce un defect a fost descoperit în program, acesta trebuie corectat și apoi revalidat sistemul. Acest lucru poate implica reinspectarea programului în cazul în care testele existente sunt executate din nou. Testarea de regresie este utilizata pentru a verifica dacă modificările aduse unui program nu au introdus noi defecte. Experiența a arătat că o mare parte din "reparații” sunt fie incomplete , fie introduc noi defecte în cadrul programului. [3.2]
În principiu, ar trebui să se repete toate testele după fiecare reparație a defectelor; în practică, acest lucru este de obicei prea scump.
3.1 Planificarea verificarii si validarii
Verificarea și validarea este un proces costisitor. Pentru unele sisteme, cum ar fi sistemele în timp real cu constrângeri nefuncționale complexe, mai mult de jumătate din bugetul sistemului de dezvoltare poate fi cheltuit pe aceste procese . [3.3]
Figura 3. Planul de testare[3.3]
Planificarea sistemului de validare si verificarea ar trebui să înceapă cat mai devreme în procesul de dezvoltare. Modelul procesului de dezvoltare software este aratat în figura de mai sus si este numit uneori modelul –V . Este o instanțiere a modelului cascada și arată că planurile de testare ar trebui să fie deduse din specificațiile sistemului și proiectare. Acest model, de asemenea, descompune sistemul de validare si verificare într-un număr de etape. Fiecare etapă este determinată prin testele care au fost definite pentru a verifica conformitatea programului cu designul și specificatiile sale. [3.3]
Ca o regulă generală, pentru un sistem mai critic, mai mult efort ar trebui să fie dedicat tehnicilor de verificare statice.
Componentele principale ale unui plan de testare pentru un sistem mare și complex sunt :
O descriere a fazelor majore ale procesului de testare
Sistemul de îndeplinire a cerințelor de testare ar trebui să fie planificat astfel încât toate cerințele sa fie testate individual.
Produsele procesului software care trebuie testate trebuie sa fie specificate.
Un program de testare și alocarea resurselor pentru acest program este, în mod evident, legat de programul mai general de dezvoltare a proiectului.
Nu este suficient sa se ruleze testele pur și simplu; rezultatele testelor trebuie să fie în mod sistematic înregistrate. Trebuie să fie posibil să se verifice procesul de testare pentru a verifica dacă a fost efectuat corect.
-
Cerințe hardware și software
Această secțiune trebuie să stabilească instrumentele software si hardware necesare și estimate utilizarii.
Constrângerile care afectează procesul de testare, cum ar fi lipsa de personal ar trebui să fie anticipate in aceasta sectiune.
Pentru sistemele mai mici, un plan de testare mai puțin formal poate fi utilizat, dar există încă o necesitate pentru un document oficial pentru a sprijini planificarea procesului de testare. Pentru unele procese agile, cum ar fi programarea extremă de testare este inseparabilă de dezvoltare. [3.3]
Planurile de testare nu sunt documente statice, dar evoluează pe parcursul procesului de dezvoltare. Planurile de testarese pot schimba din cauza întârzierilor în alte stadii în procesul de dezvoltare. În cazul în care o parte dintr-un sistem este incompletă, sistemul în ansamblul său nu poate fi testat. Atunci trebuie să se revizuiască planul de testare pentru a redistribui testerii pentru o altă activitate și aducerea înapoi, atunci când software-ul este din nou disponibil. [3.3]
3.2 Inspecțiile software
Inspecțiile software suntprocese statice , în care un sistem software este revizuit pentru a găsi erori, omisiuni și anomalii. Când se inspecteaza un sistem, se tine cont de cunoașterea sistemului, domeniul său de aplicare, limbajul de programare sau de designul modelului pentru a descoperi erori. [3.1]
Există trei avantaje majore ale inspecției:
-
În timpul testării, erorile pot ascunde alte erori. În consecință, o singură sesiune de inspecție poate descoperi multe erori într-un sistem.
-
Versiuni incomplete ale unui sistem pot fi inspectate fără costuri suplimentare. Dacă un program este incomplet, atunci este nevoie sa se dezvolte teste de specialitate pentru a verifica componentele care sunt disponibile.
-
La fel ca în căutarea pentru defecte de program, o inspecție poate lua în considerare și alte atribute de calitate ale unui program, cum ar fi respectarea standardelor, portabilitatea și întreținerea. De asemenea ne intereseaza ineficiența, existenta unor algoritmi nepotriviti sau stilul de programare sărac ce ar putea face sistemul dificil să se mențină și sa se actualizeze.
Procesul de inspecție al programului
Inspecțiile programului au ca obiectiv detectarea defectelor de program. Noțiune de un proces de control formal a fost dezvoltat pentru prima dată de IBM în anii 1970 (Fagan, 1976). Acum este o metodă de verificare a programului destul de utilizata pe scară largă, în special în ingineria sistemelor critice. Din metodă originală a lui Fagan, au fost dezvoltate o serie de abordări alternative pentru inspecție (Gilb și Graham, 1993). Diferența esențială între inspecțiile de programe și alte tipuri de revizuire a calității este că obiectivul specific al inspecțiilor este de a găsi defecte de program, mai degrabă decât să ia în considerare probleme mai largi de proiectare. Defecte pot fi erori logice, anomalii in cod , care ar putea indica o condiție eronată , nerespectarea organizarii sau standardele proiectului. [3.1]
Activitățile din procesul de inspecție sunt :
Autorul sau proprietarul - Programatorul sau proiectantul responsabil pentru producerea programului sau documentatiei. Responsabil pentru fixarea defectelor descoperite în timpul procesului de inspecție.
Inspectorul - Găsește erori, omisiuni și inconsecvențe în programe și documente. Poate identifica, de asemenea, probleme mai largi, care sunt în afara domeniul de aplicare al echipei de inspecție.
Corectorul - Prezintă codul sau documentul la o reuniune de inspecție.
Scribul - Înregistrează rezultatele reuniunii de inspecție.
Președintele sau moderatorul - Gestionează procesul și facilitează inspecția. Raporteaza rezultatele procesului la moderatorul șef.
Moderatorul general - responsabil cu îmbunătățirea procesului de inspecție, actualizarea listei de verificare, dezvoltarea standardelor, etc
Înainte de inceperea unui proces de inspectie de program, este esențial ca:
1. Sa existe o specificație exactă a codului care urmează să fie inspectat. Este imposibil sa se inspecteze o componentă la nivel de detaliu pentru a detecta defecte fără a avea o specificație completă.
2. Membrii echipei de control sa fie familiarizați cu standardele de organizare.
3. O versiunea compatibila a codului sa fie distribuita la toti membrii echipei. Nu va exista niciun punct în controlul codului, care este "aproape complet", chiar în cazul în care o întârziere provoacă întreruperi de program. [3.1]
Moderatorul echipei de inspecție este responsabil pentru planificarea inspecției. Acesta implică selectarea unei echipe de inspectie si asigurarea că materialul care urmează să fie inspectat și specificațiile sale sunt complete. Programul ce urmeaza sa fie inspectat este prezentat echipei de inspecție în etapa de prezentare generală, cand autorul codului descrie ceea ce programul este destinat să facă. Aceasta este urmată de o perioadă de pregătire individuală. Fiecare membru al echipei de inspectie studiaza specificatiile și programul si se cauta defectele în cod. [3.4]
Inspecția în sine ar trebui să fie destul de scurta (nu mai mult de două ore) și ar trebui sa se concentreze pe detectarea defectelor, standardelor de conformitate și de programarea de proasta calitate. Echipa de inspecție nu trebuie să sugereze modul în care ar trebui să fie corectate aceste defecte si nici să se recomande modificări la alte componente. [3.4]
În urma inspecției, autorul programului ar trebui să facă modificări pentru a corecta problemele identificate. În etapa de urmarire, moderatorul ar trebui să decidă dacă este necesară o reinspectie a codului. De asemenea se poate decide că nu este necesara o reinspectie completa și că defectele au fost stabilite cu succes. Programul este apoi aprobat de către moderator pentru lansare. [3.4]
Figura 4. Procesul de inspectie [3.4]
Verificari ale inspectiei [3.5]:
Defecte de date
Sunt toate variabilele programului inițializate înainte de atribuirea valorile lor care sunt folosite?
Au fost numite toate constantele?
Trebuie ca limita superioară de matrice sa fie egala cu dimensiunea matricei sau dimensiunea -1?
În cazul în care se utilizează șiruri de caractere, este un delimitator atribuit în mod explicit?
Există vreo posibilitate de supraincarcare a bufferului?
Defecte de control
Pentru fiecare afirmație condiționată, este condiția corecta?
Este stabilita pentru fiecare buclă conditia de terminare a acesteia?
Declaratiile compuse sunt corect intre paranteze?
În cazul declarațiilor, sunt toate cazurile posibile reprezentate?
Erori de intrare / ieșire
Sunt utilizate toate variabilele de intrare?
Sunt toate variabilele de ieșire atribuite unor valori înainte de a avea rezultatul programului?
Defecte de interfață
Nu toate apelurile de funcții și metode au numărul corect de parametri?
Sunt parametrii în ordinea corectă?
Dacă accesul componentelor la memoria partajată au același model ca al structurii de memorie partajată?
Erori ale managementului de stocare
Dacă legatura unei structuri este modificată, au fost corect realocate toate celelalte legaturi?
Dacă se utilizează stocarea dinamică, a fost alocat spațiu in mod corect?
Este spațiu în mod explicit dealocat după ce acesta nu mai este necesar?
Defecte de management
Au fost luate în considerare toate condițiile de eroare posibile?
3.3 Analiza statica automata
Inspecțiile sunt o forma de analiza statică –examinarea programul fără executarea aceastuia. Așa cum am discutat, inspecțiile sunt adesea conduse de liste de verificare de erori care identifică erorile comune în diferite limbaje de programare. Pentru cateva erori, este posibil să se automatizeze procesul de control al aceastei liste, care a dus la dezvoltarea de analizoare automate statice pentru diferite limbaje de programare. [3.4]
Analizoarele statice sunt instrumente software care scanează textul sursă al unui program și detecteaza eventualele defecte și anomalii. Acestea analizeaza textul de program și recunoaste astfel tipurile de declarații în program. Poate detecta apoi dacă declarațiile sunt bine formatate, face deducții despre fluxul de control în program și, în multe cazuri, poate calcula un set de valori posibile pentru toate datele de program si pot fi utilizate ca parte a procesul de inspecție sau ca o activitate distinctă a procesului de validare si verificare. [3.4]
Intenția de analiză statica automată este de a atrage atenția unui inspector la anomalii în cadrul programului, cum ar fi variabilele care sunt folosite fără inițializare, variabilele care sunt neutilizate sau date a căror valoare ar putea ieși din raza de acțiune. [3.4]
Unele dintre controalele care pot fi detectate prin analiza statica sunt :
Defecte de date
Variabilele sunt folosite inainte de initializare
Variabilele sunt declarate, dar niciodata folosite
Posibile incalcari ale declararii matricelor
Nedeclararea variabilelor
Defecte de control
Codul inaccesibil
Ramuri necondiționate în bucle
Erori de intrare / ieșire
Variabile de iesire neatribuite
Defecte de interfață
Nepotriviri ale tipului parametrului
Nepotriviri ale numărului de parametrii
Neutilizarea rezultatelor funcțiilor
Functii si proceduri neapelate
Erori ale managementului de stocare
Pointeri neasignati
Aritmetica pointerilor
Anomaliile sunt adesea rezultate ale unor erori de programare, astfel încât acestea să sublinieze lucruri care ar putea merge greșit atunci când programul este executat. Cu toate acestea, ar trebui să se înțeleagă că aceste anomalii nu sunt neapărat defecte de program. [3.1]
Etapele implicate în analiza statica includ [3.1]:
1. Controlul fluxului de analiză -- Această etapă identifică și scoate în evidență buclele cu multiple ieșiri sau punctele de intrare și codul inaccesibil. Codul inaccesibil este codul care este înconjurat prin declarații Goto necondiționate sau, care este într-o declaratie condiționata si condiția nu poate fi adevărata.
2. Analiza de utilizare a datelor -- Această etapă evidențiază modul în care sunt folosite variabile în program. Aceasta detectează variabilele care sunt folosite fără inițializare anterioara, variabilele care sunt scrise de două ori și variabilele care sunt declarate, dar nu au fost folosite niciodată. Analiza de utilizare a datelor descoperă, de asemenea, teste ineficiente în cazul în care condiția testului este redundantă. Condițiile redundante sunt condiții care sunt fie adevărate, fie false întotdeauna.
3, Analiza interfetei -- Această analiză verifică coerența de rutină, declarațiile procedurilor și utilizarea lor. Nu este necesara în cazul limbajelor de programare puternice cum ar fi Java, deoarece compilatorul efectuează aceste verificări. Analiza interfaței poate detecta erori în limbaje slabe cum ar fi FOR-TRAN și C. Analiza interfetei poate detecta, de asemenea, funcții și proceduri care sunt declarate și nu sunt apelate niciodata sau rezultate ale funcțiilor care nu sunt utilizate.
4, Analiza fluxului de informații -- Această fază a analizei identifica dependențele dintre variabilele de intrare și cele de ieșire. În timp ce nu se detectează anomalii, se arată modul în care valoarea fiecărei variabile din program este derivata din alte valori ale variabilelor. Cu aceste informații, o inspecție a codului ar trebui să poată să găsească valori care au fost calculate în mod eronat. Analiza fluxului de informații poate arăta, de asemenea, condiții care afectează valoarea unei variabile.
5, Analiza rutelor -- Această fază de analiză semantică identifică toate rutele posibile prin program și stabilește situațiile executate în această ruta. Ea dezvăluie, în esență, controlul programului și permite fiecarui posibil predicat să fie analizat individual.
Analiza statica este deosebit de valoroasa atunci când este folosit un limbaj de programare, cum ar fi C-ul. Acest lucru este deosebit de important atunci când C (și într-o măsură mai mică, C ++) este utilizat pentru dezvoltarea sistemelor. În acest caz, analiza statică poate descoperi un număr mare de erori potențiale și poate reduce semnificativ costurile de testare. [3.5]
Nu există nicio îndoială că, pentru limbaje, cum ar fi C, analiza statica este o tehnica eficienta pentru a descoperi erori de program. Cu toate acestea, designerii de limbaje de programare moderne, cum ar fi Java, au eliminat unele erori caracteristice lingvistice predispuse. Toate variabilele trebuie să fie inițializate, nu există declarații Goto, astfel codul inaccesibil este mai puțin probabil să fie creat accidental, și managementul de stocare este automat. Această abordare de evitare a erorilor este mai eficienta în îmbunătățirea fiabilității programului decât detecția erorilor. Cu toate ca analiza statica pentru Java este disponibila, aceasta nu este utilizata pe scară largă. Nu este clar dacă numărul de erori detectate justifică timpul necesar pentru a analiza rezultatelor programului. [3.5]
Prin urmare, pentru a ilustra analiza statică se foloseste un program C mic, mai degrabă decât un program Java. Sistemele UNIX si Linux includ un analizor static numit LINT pentru programele C. LINT prevede verificarea statica, care este echivalentă cu cea prevăzută de compilator într-un limbaj puternic cum ar fi Java. Un exemplu de producție realizată de LINT este prezentată în figura. [3.5]
Figura 5. Analiza statica LINT (Software engineering 8th ed) [3.5]
În aceasta transcriere a unei sesiuni de terminale Unix, comenzile sunt prezentate cu caractere cursive. Prima comandă (linia 138) enumeră ( fără sens) programul. Definește o funcție cu un parametru, numita printarray, și apoi solicită această funcție cu trei parametri. Variabile i și C sunt declarate, dar nu le sunt atribuite valori. Valoarea returnată de funcție nu este utilizata. [3.5]
Linia 139 prezinta compilarea C a acestui program cu nicio eroare raportata de către compilatorul C. Aceasta este urmată de un apel al analizorului static LINT, care detectează și raporteaza erori de program. [3.5]
Analizorul static arată că variabilele c și i au fost folosite, dar neinitializate, și că printarray a fost apelata cu un număr diferit de argumente decât a fost declarata. Identifică, de asemenea, utilizarea inconsecventă a primului argument în printarray și faptul că valoarea funcției nu a fost folosita niciodată. [3.5]
Analiza pe bază de instrument nu poate înlocui inspecții, așa cum există unele tipuri de erori pe care analizoarele statice nu le pot detecta. De exemplu, acestea pot detecta variabilele neinitializate, dar nu pot detecta initializarile care sunt incorecte. În limbaje slabe, cum ar fi C, analiza statica poate detecta funcții care au greșite numarul și tipurile de argumente, dar ei nu pot detecta situațiile în care un argument incorect de tip corect a fost trecut la o funcție. [3.5]
Pentru a aborda unele dintre aceste probleme, analizoare statice cum ar fi LCLint (Orcero, 2000;Evans și Larochelle, 2002) susțin utilizarea de adnotări în cazul în care utilizatorii definiesc constrângeri în program. Aceste constrângeri permit unui programator să precizeze că variabilele dintr-o funcție, nu ar trebui să fie schimbate, variabilele globale utilizate, și așa mai departe. Analizorul static poate verifica apoi programul împotriva acestor constrângeri și evidentierea secțiunilor de cod care par a fi incorecte. [3.5]
3.4 Metode formale si de verificare
Metodele formale de dezvoltare software se bazează pe reprezentări matematice ale software-ului, de obicei, ca o specificație formală. Ne putem gândi la utilizarea metodelor formale ca la verificarea tehnică statica finala. Pentru asta este nevoie de analize foarte detaliate ale specificatiilor sistemului și programului, iar utilizarea lor este de multe ori consumatoare de timp și costisitoare. În consecință, utilizarea metodelor formale este în mare parte limitată la securitatea critica a proceselor de dezvoltare software. [3.1]
Metodele formale pot fi folosite în diferite etape in procesului de verificare si validare[3.1]:
1. O specificație formală a sistemului poate fi dezvoltata și analizata matematic pentru inconsecvențe. Această tehnică este eficientă în descoperirea erorilor și omisiunilor din documentatie.
2. Puteți verifica în mod formal, folosind argumente matematice, că codul unui sistem sofware este în conformitate cu specificatiile sale. Acest lucru necesită o specificație formală și este eficienta în descoperirea unor erori de proiectare.
Argumentul pentru utilizarea specificației formale și verificarea programului asociat este ca specificația formală forțează o analiză detaliată a caietului de sarcini. Aceasta poate dezvălui potențiale inconsecvențe sau omisiuni care nu ar putea fi altfel descoperite până când sistemul este operațional. Verificarea formala demonstrează că programul dezvoltat respectă specificațiile sale, astfel erorile implementate să nu compromită fiabilitatea. [3.1]
Argumentul împotriva utilizării specificațiilor formale este că necesită notații de specialitate.
Inginerii software nu pot recunoaște potențialele dificultăți ale cerințelor pentru că nu înțeleg domeniul. Cu toate ca specificatiile pot fi substantiale din punct de vedere matematic, acestea nu pot specifica sistemului proprietățile care sunt într-adevăr necesare. [3.1]
Verificarea unui sistem software nontrivial necesita mult timp și instrumente specializate, cum ar fi expertiza teoremelor matematice. Prin urmare, este un proces extrem de costisitor și, care crește dimensiunea sistemului, costurile de verificare formală crascand în mod disproporționat. Prin urmare, mulți oameni cred că verificarile formale nu sunt costisitoare si eficiente. Același nivel de încredere în sistem poate fi realizat mai ieftin prin folosirea altor tehnici de validare, precum inspecții și testarea sistemului. [3.1]
Acesta este, uneori, susținut de faptul ca utilizarea metodelor formale pentru dezvoltarea sistemului conduce la sisteme mai fiabile și mai sigure. Nu există nicio îndoială că specificatiile unui sistem formal este mai puțin probabil să conțină anomalii care trebuie rezolvate de către designerul sistemului. Cu toate acestea, specificatiile formale nu garantează că software-ul va fi de încredere în utilizarea practică. Motivele pentru aceasta sunt:
1. Specificațiile pot să nu reflecteze cerințele reale ale utilizatorilor sistemului. Lutz (Lutz, 1993) a descoperit că multe eșecuri experimentate ale utilizatorilor au fost o consecință de erori și omisiuni ale specificatiilor care nu au putut fi detectate de sistemul formal. În plus, utilizatorii sistemului rareori înțeleg notațiile formale astfel încât acestia nu pot citi caietul de sarcini oficial pentru a găsi direct erori și omisiuni.
2. Verificarea poate contine erori. Verificarea programului este mare si complexa, așa, ca programele mari și complexe, conțin si ele, de obicei, erori.
3. Verificarea poate presupune un model de utilizare care este incorect. Dacă sistemul nu este folosit anticipat, verificarea poate fi invalida.
În ciuda dezavantajelor lor, metodele formale au un rol important în dezvoltarea de sisteme software critice. Specificațiile formale sunt foarte eficiente în a descoperi problemele de specificație care sunt cele mai frecvente cauze ale eșecului sistemului. Verificarea formala creste încrederea în cele mai critice componente ale acestor sisteme. Utilizarea acestor abordări formale este în creștere și ca tot mai multi ingineri se familiarizeaza cu aceste tehnici. [3.1]
Dezvoltare de software de curatare, Cleanroom
Un model al procesului de curatare este prezentat în figura .
Figura 6. Procesul de curatare [3.1]
Obiectivul aceastei abordari a dezvoltării software este un software cu zero defecte. Numele "Cleanroom" a fost derivat prin analogie cu unitățile de fabricație în cazul în care defectele semiconductoarelor sunt evitate prin fabricarea într-o atmosferă extrem de curata. Dezvoltarea „cleanroom” este deosebit de relevanta pentru acest capitol, deoarece a fost înlocuita testarea unității componentelor sistemului de inspecții pentru a verifica coerența acestor componente cu specificațiile lor. [3.1]
Abordarea Cleanroom pentru dezvoltarea software se bazează pe cinci strategii cheie:
-
Specificație formală
Software-ul care urmează să fie dezvoltat este specificat în mod formal. Un model de tranzitie al starilor care arată răspunsurile sistemului la stimuli este folosit pentru a exprima specificatiile softului.
-
Dezvoltarea incrementală
Software-ul este împărțit în trepte, care sunt dezvoltate și validate separat folosind procedeul Cleanroom. Aceste etape sunt specificate, cu clientul, într-un stadiu incipient în proces.
-
Programarea structurata
Doar un număr limitat de control și abstractizare a datelor sunt utilizate. Procesul de dezvoltare al programului este un proces de rafinare treptată a specificatiilor. Un număr limitat de construcții sunt utilizate și scopul este de a transforma în mod sistematic specificația pentru a crea codul programului.
-
Verificarea statică
Dezvoltarea software este static verificata cu ajutorul inspecțiilor software riguroase. Nu există nicio unitate sau modul de testate pentru codul componentelor.
-
Testarea statistică a sistemului
Creșterea software-ului integrat este testat statistic pentru a determina fiabilitatea. Aceste teste statistice sunt bazate pe un profil operațional, care este dezvoltat în paralel cu specificațiile sistemului aratat în figura precedenta.
Există trei echipe implicate atunci când procesul Cleanroom este utilizat pentru sistemele de dezvoltare mari[3.1]:
1. Echipa de specificatii -- Acest grup este responsabil pentru dezvoltarea și menținerea specificațiilor sistemului. Aceasta echipa produce specificatii orientate spre client (definiția cerințelor utilizatorilor) și specificațiile matematice pentru verificare. În unele cazuri, atunci când specificațiile sunt complete, echipa de specificatii este, de asemenea, responsabila pentru dezvoltare.
2. Echipa de dezvoltare -- Această echipă are responsabilitatea de a dezvolta și verifica software-ul. Software-ul nu este executat în timpul procesului de dezvoltare.
3. Echipa de certificare -- Aceasta echipa este responsabila pentru dezvoltarea unui set de teste statistice pentru a exercita software-ul după ce a fost dezvoltat. Aceste teste sunt bazate pe specificația formală. Dezvoltarea testelor se efectuează în paralel cu dezvoltarea de software. Cazurile de test sunt utilizate pentru a certifica fiabilitatea software-ului. Modelele de creștere a fiabilitatii pot fi utilizate pentru a decide când se poate opri testarea.
Utilizarea abordării Cleanroom a dus, în general, la un software cu foarte puține erori. Abordarea de dezvoltare incrementală în procesul Cleanroom este de a oferi funcționalitate clientui în trepte, din timp. Funcții mai puțin importante de sistem sunt incluse în pași mai târzii. Prin urmare, clientul are posibilitatea de a încerca aceste creșteri critice înainte de livrarea întregului sistem. Dacă probleme ale cerințelor sunt descoperite, clientul isi spune parearea echipei de dezvoltare despre aceste informații și solicită o nouă versiune. [3.1]
Inspecția riguroasa a programului este o parte fundamentală a procesului Cleanroom. [3.1]
Argumentele matematice utilizate în procesul Cleanroom nu sunt, cu toate acestea, dovezi formale ale corectitudinii. Dovezi matematice formale prin care un program este corect în ceea ce privește specificația sa sunt prea scumpe pentru a fi dezvoltate. Acestea depind de cunoașterea semanticii formale ale limbajului de programare pentru a construi teorii care reprezinta programul și caracteristicile formale ale acestuia. Aceste teorii trebuie să fie dovedite apoi matematic. Din cauza costului ridicat și competențelor de specialitate care sunt necesare, acestea sunt de obicei elaborate numai pentru aplicațiile critice de securitate. [3.1]
Inspecția și analiza formală a fost dovedit a fi foarte eficiente în procesul cleanroom. Marea majoritate a defectelor sunt descoperite înainte de executare și nu sunt introduse în software-ul dezvoltat. Linger (Linger, 1994) a raportat că, în medie, au fost descoperite doar 2.3 defecte la mia de linii de cod sursă în timpul testarii pentru proiectele Cleanroom. Costurile totale de dezvoltare nu sunt crescute deoarece este nevoie de mai puțin efort pentru a testa și repara software-ul dezvoltat. S-a descoperit ca cele mai multe echipe ar putea folosi cu succes metoda Cleanroom. Programele produse au fost de o calitate mai buna decât cele dezvoltate folosind tehnici tradiționale - codul sursă a avut mai multe comentarii și o structură simplista. Dezvoltarea cleanroom funcționează atunci când este practicata de ingineri calificați și dedicați. [3.1]
3.5 Puncte cheie
Verificarea și validarea nu sunt același lucru. Verificarea este destinata să demonstreze că un program îndeplinește caietul de sarcini. Validarea este destinata să demonstreze că programul face ceea ce utilizatorul cere. [3.1]
■ Planurile de testare ar trebui să includă o descriere a elementelor care urmează să fie testate, programul de testare, procedurile de gestionare a procesului de testare, cerințele hardware și software, precum și orice problema de testare care poate să apară.
■ Tehnicile de verificare statice implica examinarea și analiza codului sursă al programului pentru a detecta erorile. Acestea ar trebui să fie utilizate cu testarea programului, ca parte a procesului de validare si verificare.
■ Inspecțiile de program sunt eficiente în găsirea erorilor de program. Scopul este de
localizare a defectelor. O listă de verificare a defectelor trebuie să conducă procesul de inspecție.
■ Într-o inspecție de program, o echipă mică verifică sistematic codul. Membrii echipei includ un lider de echipă sau moderator, autorul codului, un cititor care prezintă codul în timpul inspecției și un tester care prezinta codul dintr-o perspectivă de testare.
■ Analizele statice sunt instrumente software care prelucrează un cod sursă de program și atrage atenția asupra anomaliilor, cum ar fi secțiuni de cod neutilizate și variabile neinitializate. Aceste anomalii pot fi rezultatul unor defecte in cod.
■ Dezvoltarea software Cleanroom se bazează pe tehnici statice pentru verificarea programului și testarea statistică pentru certificarea fiabilitatii sistemului. Acesta a fost de succes în producerea de sisteme care au un nivel ridicat de fiabilitate.
Bibliografie:
Capitolul 1:
1.1) "Management Information Systems: Managing the Digital Firm" (ed. 11). Laudon, K., & Laudon, J.
1.2) “Software Engineering” ed. 8 – I. Sommerville
1.3) “The Unified Software Development Process” - Ivar Jacobson, Grady Booch, James Rumbaugh
Capitolul 2:
2.1) “Software Engineering” 8th Edition – Ian Sommerville
2.2) “Software Testing” - Jiantao Pan
2.3) ”Introduction to Software Testing” - Paul Ammann, Jeff Offutt
2.4) ”Foundations of Software Testing” - Mathur, Aditya P
2.5) ”Part of the Pipeline: Why Continuous Testing Is Essential” - Adam Auerbach,
Capitolul 3:
3.1 ) “Software engineering”, ed. VIII, Addison Wesley, 2007 - A. Sommerville
3.2) „Verification, Validation and Testing in Software Engineering 1st Edition” - Aristides Dasso and Ana Funess
3.3) „Software Verification and Validation- An Engineering and Scientific Approach” - Fisher, Marcus S.
3.4) https://users.ece.cmu.edu/~koopman/des_s99/verification/
3.5) http://softwaretestingfundamentals.com/verification-vs-validation/
Dostları ilə paylaş: