La ce este bună de fapt „testarea condițiilor” (așa cum este definită de ISTQB Syllabus)? [duplicat] (Inginerie software, Testare, Condiții, Acoperire De Testare)

David Tonhofer a intrebat.
a intrebat.

În prezent, verific prin syllabus-ul pentru certificarea ISTQB „Technical Test Analyst”. Acest syllabus (denumit de acum înainte „syllabus TTA”) conține un capitol dedicat „testarea condițiilor” (se pare că aceasta se mai numește și „acoperirea condițiilor” sau „testare de acoperire a condițiilor„.)

Testarea condițiilor așa cum este definit în programa TTA mi se pare un lucru extrem de ciudat și posibil anacronic, care are mai mult de-a face cu Povestea cu șuncă a bunicii decât cu testarea software. Permiteți-mi să vă explic…

Ce este „testarea condițiilor” în conformitate cu programa TTA?

Făcând referire la „Advanced Level Syllabus – Technical Test Analyst, Version 2012” al ISTQB, disponibil aici, , „testarea condițiilor” este definită după cum urmează la pagina 12:

În comparație cu testarea deciziilor (ramură), care ia în considerare întreaga decizie ca întreg și evaluează rezultatele ADEVĂRAT și FALS în cazuri de testare separate, testarea condițiilor ia în considerare modul în care este luată o decizie. Fiecare predicat de decizie este alcătuit din una sau mai multe condiții „atomice” simple, fiecare dintre acestea fiind evaluată la o valoare booleană discretă. Acestea sunt combinate logic pentru a determina rezultatul final al deciziei. Fiecare condiție atomică trebuie să fie evaluată în ambele sensuri de către cazurile de testare pentru a atinge acest nivel de acoperire.

Aplicabilitate

Testarea condițiilor este probabil interesantă doar în abstract din cauza dificultăților menționate mai jos. Cu toate acestea, înțelegerea sa este necesară pentru a obține niveluri mai mari de acoperire care se bazează pe aceasta.

Să clarificăm, așadar, cuvintele

Să presupunem că avem un software supus testului asupra căruia dorim să facem testarea cutiei albe (adică avem codul sursă). Codul conține, în mod natural, multe dintre acele predicte de decizie pe care le cunoaștem și le iubim cu toții și care apar după șiruri de caractere precum if, , while, , until etc.

Un exemplu de predicat de decizie ar putea fi:

((x>y+z) AND (y<-3)) OR ((z²+x²<4) AND (z≤y))

Acest predicat de decizie acceptă o triplă (x,y,z) de valori întregi (să zicem) și emite un boolean, b_out.

Funcțiile de prim nivel care mapează (x,y,z) la {TRUE,FALSE} se numesc condiții (de asemenea condiții atomice) în programa de studiu TTA.

Acoperirea testării condițiilor

Se obține „acoperirea testării condițiilor” prin rularea cazurilor de testare până când toate condiții găsite în decizie au dat cel puțin o dată adevărat și cel puțin o dată falsă.

Astfel, se poate obține o acoperire a testării condițiilor prin rularea următoarelor cinci cazuri de testare (de exemplu):

Fiecare dintre b0, , b1, , b2, , b3 apare cel puțin o dată cu adevărat și cel puțin o dată cu fals. În unele cazuri de testare, nu ne pasă de o anumită valoare, deoarece aceasta nu are nicio influență asupra condiției a cărei ieșire dorim să fie corectă.

Addenda: Acoperirea deciziei

De altfel, tabelul de adevăr arată, de asemenea, că „acoperirea deciziei” a fost atinsă pentru această decizie, deoarece b_out apare cel puțin o dată cu adevărat și cel puțin o dată cu fals, , astfel încât ambele ramuri ale oricărui cod ar fi acoperite.

Și acum întrebarea

La ce servește de fapt „testarea condițiilor”, așa cum a fost definită mai sus?

Nu vă va ajuta deloc să constatați corectitudinea predicatului de decizie.

Aceasta se face cel mai bine printr-o inspecție a codului, lăsând o a doua echipă să scrie aceeași expresie și comparând ieșirile sau rulând cazuri de testare la „valori limită” (de exemplu, aici, pentru y = -4, -3, -2).

Verificarea condițiilor individuale mi se pare că este mai degrabă o verificare a ALU a procesorului sau poate o verificare a ieșirii compilatorului. Cu siguranță este potrivită pentru verificarea codului de asamblare scris manual sau pentru verificarea logicii asamblate manual.

Iar acest lucru mă face să mă gândesc că „testarea condițiilor” ar putea foarte bine să fie o rămășiță din zilele în care condițiile erau de fapt cablate pe panouri (de exemplu în ENIAC) și, prin urmare, ar putea face obiectul unor erori de cablare. În zilele noastre, condiția este scrisă în cod de nivel înalt și este exact cea pe care o doriți din punct de vedere conceptual. În timp ce revizuirea ar putea fi utilă, o testare a condiției este doar o pierdere de timp.

Sau îmi scapă ceva?

Addenda: Căutarea literaturii

O căutare a biblioteca IEEE Xplore pentru „condition testing” (testarea condițiilor) a dat numai două lucrări relevante pentru software (toate celelalte par a fi relevante numai pentru hardware), ambele scrise de K.C. Tai de la Departamentul de Informatică al Universității de Stat din Carolina de Nord.

Verificarea uneia dintre acestea, Strategii de testare a software-ului bazate pe condiții arată că autorul folosește termenul condiție în sensul de decizie de mai sus, adică în această lucrare „testarea condițiilor” este de fapt „testarea deciziilor”. La condiție așa cum este utilizată în programa TTA se numește condiție simplă. Se pare că definițiile din programa TTA nu sunt utilizate pe scară largă.

Din rezumat:

Un program de calculator este format din instrucțiuni, cum ar fi instrucțiunile IF și WHILE, care conțin condiții, care sunt combinații de expresii booleene și relaționale. O abordare de testare, denumită testarea condițiilor, , este de a testa un program, concentrându-se pe testarea condițiilor din acest program. Au fost dezvoltate o serie de strategii de testare a condițiilor, dar acestea nu sunt eficiente pentru detectarea erorilor în condiții complicate. În această lucrare, definim două strategii de testare a condițiilor, bazate pe detectarea expresiilor booleene și relaționale [de exemplu, expresii de forma E1 op E2, unde E1 și E2 sunt expresii aritmetice și op este unul dintre cei șase operatori relaționali posibili: < <=, =, =, !=, >, >=] erori într-o condiție. Pentru aceste două strategii de testare a condițiilor, prezentăm câteva proprietăți teoretice și explicăm de ce sunt practice și eficiente pentru testarea programelor care conțin condiții complicate.

Comentarii

  • Acesta NU este un duplicat al articolului „Este acoperirea testelor o măsură adecvată a calității codului?”. Chiar aș vrea să știu cum poate cineva să ajungă la această concluzie. Aceasta este despre „testarea condițiilor”, pentru început. „Testarea condițiilor” este o caz specific de acoperire. Poate că ar trebui să împachetăm Mathoverflow pentru că oricum totul se rezumă la „funcții”? –  > Por David Tonhofer.
  • Nu știu de unde ai scos ideea că acoperirea condițiilor (sau orice altă măsură de acoperire a codului) are vreo legătură cu „corectitudinea” codului. Nu are nimic de-a face cu aceasta. Astfel de măsurători sunt o modalitate de a măsura completitudinea a suitei de teste, nimic mai mult. Iar unele măsurători de acoperire sunt mai bune decât altele în acest sens. În cazul condiție este o măsură mai bună/mai puternică decât acoperirea ramurilor/deciziilor sau acoperirea declarațiilor. Aceasta este motivul pentru care acoperirea condițiilor merită să fie cunoscută. –  > Por Rogério.
  • @Rogério A trecut ceva timp, dar probabil pentru că se numește „condition testing” și nu „subcondition coverage testing”. Este în continuare un exercițiu inutil pentru că de ce ar vrea cineva să acopere spațiul N-dimensional al variabilelor de intrare ale condiției? Cu excepția cazului în care acest lucru este făcut de persoana care proiectează condiția – caz în care aceasta va lua codul care exprimă condiția și îl va testa separat folosind câteva cazuri de testare, dar nu și în codul produsului final. Am putea spera… –  > Por David Tonhofer.
  • Din primul citat din întrebare (care menționează „condiții atomice”), vedem că o „condiție” este ceea ce dumneavoastră numiți „subcondiție”. Adică, în if (a && b) decizie, avem două condiții, a și b care sunt evaluate separat (la adevărat/false fiecare, cu b este evaluată doar atunci când a este adevărată) pentru a produce rezultatul adevărat/false al deciziei/branșei. Astfel, pentru o acoperire completă a deciziei/ramurii, sunt suficiente două teste, în timp ce pentru o acoperire completă a condițiilor sunt necesare trei teste, iar aceste trei teste acoperă și rezultatele adevărate și false ale deciziei (adică ambele ramuri). –  > Por Rogério.
2 răspunsuri
Robert Harvey

Testarea condițiilor este o consecință directă a faptului că fiecare if din software-ul dvs. creează o „bifurcație” (în esență, descompunerea codului dvs. în două bucăți de cod separate), crescând astfel complexitatea ciclică globală a codului dvs.

Pentru a obține o acoperire completă a codului într-un scenariu de testare cu cutie albă, trebuie să aveți cunoștințe despre if condiții, astfel încât să vă puteți asigura că fiecare ramură de cod este exersată în timpul testării.

În ceea ce privește „corectitudinea” codului, aceasta poate fi verificată scriind semnificativ teste unitare semnificative. Adică, pentru fiecare intrare care exercită o anumită cale din cod, vă puteți aștepta la o ieșire, al cărei rezultat să demonstreze că a fost obținută corectitudinea pe care o urmăriți.

Prin „semnificative”, mă refer la faptul că, în general, testele unitare vor demonstra că un anumit contract sau cerință a fost îndeplinit. Dar tot trebuie să vă asigurați că exersați toate căile de cod, astfel încât să nu existe surprize neplăcute mai târziu.

Comentarii

  • Dar pentru asta există „testarea deciziilor” și despre asta este vorba în „acoperirea deciziilor”. Obțineți adevărat sau fals la decizie, așa că mergeți pe cele două ramuri (încă nu este o măsurătoare utilă, dar aceasta este o altă discuție) –  > Por David Tonhofer.
  • Atunci despre ce este vorba în întrebarea dumneavoastră? Vezi editarea mea ninja în timp ce îți scriai comentariul. –  > Por Robert Harvey.
  • Editarea ta ninja este corectă. Întrebarea se reduce la: De ce să menționezi testarea condițiilor în cadrul unui program de studiu pentru o certificare profesională? Pare fie inadecvat, fie adecvat altor probleme. Testarea deciziilor are propriul său capitol în programă – aceasta este ceea ce acoperirea deciziilor se referă — și are într-adevăr sens (mai puțin astăzi decât în zilele COBOL și FORTRAN. Acum pot apărea excepții și pot fi transmise funcții întregi, atașate la obiecte în timpul execuției sau chiar construite din mers). Ar trebui să scriu ISTQB pentru a elimina pur și simplu bagajul testării condițiilor 🙂 –  > Por David Tonhofer.
  • Bagaj? Se pare că nu mi-am expus cazul foarte bine. Am scris cu bold cel mai important paragraf din răspunsul meu. –  > Por Robert Harvey.
  • Nu – testele unitare nici măcar nu intră în discuție, nici contractele sau cerințele (nu vă faceți griji, știu despre acestea). Puteți face teste de condiție doar prin ruperea decizie, , apoi testați condițiile sale. Dar asta nu vă spune nimic despre nimic. Cu excepția cazului în care sunteți testați hardware-ul care implementează condiția! –  > Por David Tonhofer.
David Tonhofer

Cel mai bun răspuns pe care l-am putut găsi (și care se aplică și la testarea acoperirii declarațiilor și la alte tipuri de testare a acoperirii) este dat de această pagină de pe atollic.com „De ce analiza de acoperire a codului?”

Din punct de vedere mai tehnic, analiza de acoperire a codului găsește zonele din programul dvs. care nu sunt acoperite de cazurile de testare, permițându-vă să creați teste suplimentare care acoperă părți ale programului care altfel nu ar fi fost testate. Prin urmare, este important să înțelegeți că acoperirea codului vă ajută să înțelegeți calitatea procedurilor dvs. de testare, nu calitatea codului în sine.

Iar acest lucru pare să fie destul de relevant în acest caz. Dacă aveți un set de cazuri de testare care reușește să seteze condițiile individuale ale oricărei decizii la ADEVĂRAT sau FALS, atunci este foarte probabil să invocați codul testat cu un set destul de exhaustiv de valori de intrare!

O bună acoperire a condițiilor nu vă spune prea multe despre codul testat (cu excepția cazului în care codul explodează sau generează defecte detectabile), dar vă oferă încredere în setul de cazuri de testare.

Addenda:

Această interpretare este corectă. În lucrarea Efectul structurii programului și a modelului asupra acoperirii adecvate a testelor MC/DC (Ajitha Rajan și Mats Heimdahl, Universitatea din Minnesota, ICSE, 2008), , care se referă la „Acoperirea modificată a condițiilor/deciziilor” (MC/DC), se citește:

Adecvarea suitelor de teste se măsoară în prezent cu ajutorul metricii MC/DC pe codul sursă (sau pe un model în dezvoltarea bazată pe model) … Măsurătorile de adecvare a testelor definite pe structura unui program, cum ar fi acoperirea declarațiilor, acoperirea ramurilor și acoperirea deciziilor, au fost utilizate timp de zeci de ani pentru a evalua adecvarea suitelor de teste. Astfel de criterii pot fi instrumente utile la evaluarea unui efort de testare.

Lucrarea concluzionează, de asemenea, că acoperirea MC/DC este foarte sensibilă la structura SUT. Rearanjamentele pur sintactice pot schimba dramatic acoperirea MC/DC. Acest lucru se datorează, desigur, faptului că MC/DC lucrează doar asupra sintaxei, nu și asupra fluxului de date și, prin urmare, este o măsură destul de suspectă în orice caz. Dar aceasta este o problemă complet diferită.

Comentarii

  • acest lucru pare să repete pur și simplu ceea ce a fost afirmat într-un alt răspuns la o întrebare duplicată –  > Por gnat.
  • @gnat Da, și ce dacă? Mi s-a părut că se aplică de fapt la tuturor teste de acoperire, așa că am adăugat-o și acolo. În mod surprinzător, am primit deja două downvotes fără niciun comentariu cu privire la motiv. Acest lucru pare să indice o anumită stare tristă a comunității de testare. „Doar ceremonie, dar fără înțelegere”, cred eu. Toate aceste măsuri de acoperire mi se par la limita inutilității. Cu excepția găsirii codului mort, iar pentru asta analiza statică este oricum cea mai bună. –  > Por David Tonhofer.