Ce este testarea mutațiilor? (Exemplu)
⚡ Rezumat inteligent
Testarea mutațiilor introduce în mod deliberat mici erori în codul sursă și apoi rulează suita de teste existentă pentru fiecare versiune defectă, măsurând dacă acele teste sunt suficient de puternice pentru a detecta schimbarea.
Ce este testarea mutațiilor?
Testarea mutațiilor este un tip de testare software în care anumite instrucțiuni ale codului sursă sunt modificate sau mutate pentru a verifica dacă cazurile de testare pot găsi erori în codul sursă. Scopul testării mutațiilor este de a asigura calitatea cazurilor de testare în ceea ce privește robustețea, astfel încât acestea să eșueze în fața codului sursă mutat.
Schimbarea făcută într-un program mutant trebuie să fie menținută extrem de mică, astfel încât să nu afecteze obiectivul general al programului. Testarea mutațiilor este numită și o strategie de testare bazată pe erori, deoarece implică crearea deliberată a unei erori în program. Este o formă de Alb Box Testarea care se aplică în principal în timpul Testarea unității.
Testarea mutațiilor a fost propusă în 1971 într-o lucrare studențească de Richard Lipton și formalizată în lucrarea din 1978 „Hints on Test Data Selection” de DeMillo, Lipton și Sayward. A pierdut din avânt față de costul de calcul al vremii și de atunci a recâștigat teren pentru limbaje precum Java, C#, Python, JavaScript și XML.
Cum se execută testarea mutațiilor?
Următorii sunt pașii pentru a executa testarea mutațiilor, cunoscută și sub denumirea de analiză a mutațiilor:
Pasul 1: Erorile sunt introduse în codul sursă al programului prin crearea mai multor versiuni numite mutante. Fiecare mutant ar trebui să conțină o singură eroare, iar scopul este de a provoca eșecul versiunii mutante, ceea ce demonstrează eficacitatea cazurilor de testare.
Pasul 2: Cazurile de testare sunt aplicate programului original și, de asemenea, programului mutant. A Caz de testare ar trebui să fie adecvat și este ajustat pentru a detecta erorile într-un program.
Pasul 3: Comparați rezultatele programului original și ale programului mutant.
Pasul 4: Dacă programul original și programul mutant generează ieșiri diferite, atunci mutantul este eliminat de cazul de testare. Prin urmare, cazul de testare este suficient de bun pentru a detecta schimbarea dintre programul original și cel mutant.
Pasul 5: Dacă programul original și programul mutant generează același rezultat, mutantul este menținut în viață. În astfel de cazuri, trebuie create cazuri de testare mai eficiente care să elimine toți mutanții.
Diagrama de mai jos tracUrmează aceiași cinci pași, de la programul original, trecând prin generarea de mutanți, până la verdictul de ucis sau supraviețuitor.
Cum se creează programe mutante?
O mutație nu este altceva decât o singură modificare sintactică adusă unei instrucțiuni de program. Fiecare program mutant ar trebui să difere de programul original cu exact o mutație.
| Programul original | Programul Mutant |
| Dacă (x>y) Tipăriți „Bună ziua” Altfel Tipăriți „Bună” |
Dacă (x Tipăriți „Bună ziua” Altfel Tipăriți „Bună” |
În perechea de mai sus, doar operatorul de comparație s-a modificat, însă un caz de test în care x este mai mare decât y afișează acum „Salut” în loc de „Salut”. Ilustrația arată acea modificare sintactică.
Ce trebuie schimbat într-un program mutant?
Există mai multe tehnici care pot fi utilizate pentru a genera programe mutante. Cele trei familii de mai jos acoperă majoritatea operatorilor de mutație incluși în instrumente.
| Operaşi operatori de înlocuire | Operatori de modificare a expresiilor | Operatori de modificare a instrucțiunilor |
| Înlocuiți operandul cu un alt operand (x cu y sau y cu x) sau cu o valoare constantă. | Înlocuirea unui operator sau inserarea unui operator nou într-o instrucțiune de program. | Instrucțiunile programatice sunt modificate pentru a crea programe mutante. |
| Exemplu: Dacă(x>y) înlocuiți valorile x și y Dacă(5>y) înlocuiți x cu constanta 5 |
Exemplu: Dacă(x==y) Putem înlocui == cu >= și avem programul mutant ca If(x>=y) și inserând ++ în instrucțiune Dacă(x==++y) |
Exemplu: Ștergeți partea else dintr-o declarație if-else Ștergeți întreaga instrucțiune if-else pentru a verifica cum se comportă programul |
Câțiva operatori de mutație exemplificați:
- GOTO înlocuirea etichetei
- Înlocuire declarație de returnare
- Ștergerea declarației
- Inserarea operatorilor unari (cum ar fi – și ++)
- Înlocuirea conectorului logic
- Înlocuire comparabilă de nume de matrice
- Eliminarea părții else a unei instrucțiuni if-else
- Adăugarea sau înlocuirea operatorilor
- Înlocuirea declarației prin modificarea datelor
- Modificarea datelor pentru variabile
- Modificarea tipurilor de date în program
Operatori care ating o condiție limită supraviețuiesc cel mai adesea, așa că rezultatele mutațiilor indică frecvent lacune în analiza valorii la limită.
Tipuri de testare a mutațiilor
In Inginerie SoftwareTestarea mutațiilor este clasificată fundamental în trei tipuri - mutație a afirmațiilor, mutație a valorii și mutație a deciziilor.
- Mutația declarației – o instrucțiune este tăiată, lipită sau ștearsă, astfel încât rezultatul poate fi eliminarea unor linii de cod.
- Mutația valorii – valorile parametrilor primari și ale constantelor sunt modificate, de exemplu, schimbarea unei limite a buclei sau a unui prag.
- Mutație de decizie – instrucțiunile de control sunt modificate, de exemplu flipping un operator relațional sau negarea unei condiții.
Instrumentele își grupează operatorii sub aceste trei titluri, astfel încât familia care a produs un mutant supraviețuitor îi spune testerului ce tip de aserțiune lipsește. Un mutant de decizie supraviețuitor marchează de obicei o ramură netestată, care se suprapune cu testarea în buclă.
Automatizarea testării mutațiilor
Testarea mutațiilor consumă extrem de mult timp și este complicat de executat manual, așa că este recomandabil să se utilizeze instrumente de automatizare, care reduc și costurile. Un instrument de mutație compilează mutanții, programează rulările, înregistrează ce mutant a fost eliminat de fiecare test eșuat și raportează scorul.
Lista instrumentelor disponibile:
- Stryker — un cadru open-source pentru testarea mutațiilor cu ediții pentru JavaScript și TypeScript (StrykerJS), C# și .NET (Stryker.NET) și Scala (Stryker4s).
- PIT, scris și PITest — un sistem de testare a mutațiilor pentru Java și JVM-ul care modifică bytecode-ul compilat și se conectează la Maven și Gradle construiește alături JUnit.
Ambele rulează ca un pas de construire, deci aparțin aceleiași integrare continuă conductă ca și restul testarea automatizării pe.
Scorul de mutație
Scorul de mutație este definit ca procentul de mutanți uciși din numărul total de mutanți.
Scor mutație = (Mutanți uciși / Numărul total de mutanți) * 100
Formula este prezentată mai jos în forma în care o raportează majoritatea instrumentelor.
Cazurile de testare sunt descrise ca fiind adecvate pentru mutație atunci când scorul atinge 100%. În practică, numitorul trebuie să excludă mutanți echivalenți — mutanți a căror sintaxă modificată se comportă exact ca originalul, deci niciun test nu îi poate elimina. Prin urmare, instrumentele raportează mutanții eliminați împărțit la mutanții neechivalenți eliminați plus mutanții neechivalenți supraviețuitori și permit testerului să semnaleze echivalențele.
Rezultatele experimentale au arătat că testarea mutațiilor este o modalitate eficientă de a măsura adecvarea cazurilor de testare. Principalul dezavantaj este costul generării mutanților și al executării fiecărui caz de testare pentru fiecare dintre ei.
Testarea mutațiilor vs. Code Acoperire
Înalt acoperirea testului nu demonstrează teste puternice. Acoperirea liniilor și ramurilor înregistrează ce instrucțiuni au rulat, nu dacă ceva a fost verificat ulterior, astfel încât un test care apelează o metodă și nu afirmă nimic este totuși considerat acoperit. Testarea mutațiilor elimină această lacună, deoarece un mutant moare doar atunci când o aserțiune eșuează efectiv.
| Aspect | Code acoperire | Scorul mutației |
| Ce măsoară | Ce linii sau ramificații au executat testele | Ce defecte injectate au detectat testele |
| Sensibil la afirmații | Nu — un test cu zero aserțiuni adaugă în continuare acoperire | Da — un mutant supraviețuiește atunci când nicio afirmație nu eșuează |
| Costul unei curse | O rulare de testare instrumentată | Un singur test per mutant supraviețuitor, deci mult mai lent |
| Utilizare tipică | O portiță rapidă pentru fiecare commit | O verificare periodică mai aprofundată a modulelor critice |
| Modul de eșec | Acoperire 100% fără verificare reală | Mutanți echivalenți care nu pot fi niciodată uciși |
Cele două valori sunt complementare. Acoperirea denumește codul care nu a fost niciodată atins; scorul de mutație denumește codul atins care nu a fost niciodată verificat. Ambele alimentează aceleași informații. procesul de management al defectelor, alături de măsuri precum densitatea defectelor.
Avantajele testării mutațiilor
Următoarele sunt avantajele testării mutațiilor:
- Este o abordare puternică pentru obținerea unei acoperiri ridicate a programului sursă.
- Testează însăși suita de teste, pe care nicio altă tehnica de testare a software-ului face direct.
- Testarea mutațiilor oferă dezvoltatorului de software un nivel bun de detectare a erorilor.
- Metoda descoperă ambiguități în codul sursă și are capacitatea de a expune erori pe care execuțiile obișnuite nu le ating niciodată.
- Mutanții supraviețuitori sunt acționabile: fiecare numește o linie specifică și o schimbare specifică pe care suita nu a reușit să le observe.
- Clienții beneficiază de această testare, primind un sistem mai fiabil și mai stabil.
Dezavantajele testării mutațiilor
Pe de altă parte, următoarele sunt dezavantajele testării mutațiilor:
- Testarea mutațiilor este extrem de costisitoare și consumatoare de timp, deoarece trebuie generat și compilat un număr mare de programe mutante.
- Întrucât necesită mult timp, este corect să spunem că această testare nu poate fi realizată fără un instrument de automatizare.
- Fiecare mutant este exersat de același număr de cazuri de testare ca și programul original, așa că o populație mare de mutanți trebuie rulată împotriva întregii suite de teste.
- Mutanții echivalenți nu pot fi uciși prin niciun test, iar separarea lor de supraviețuitorii autentici necesită de obicei o revizuire manuală.
- Deoarece metoda modifică codul sursă, nu este aplicabilă pentru Negru Box Testarea.
Când se utilizează testarea mutațiilor
Profilul de costuri de mai sus înseamnă că testarea mutațiilor este rareori executată pe o bază de cod întreagă la fiecare commit. Se amortizează singură acolo unde o eroare nedetectată este costisitoare, iar codul testat este suficient de mic pentru a muta rapid.
- Logică critică pentru siguranță sau financiară — calcularea plăților, regulile fiscale și verificările autorizațiilor, unde un răspuns greșit silențios este mai rău decât un accident.
- Suite cu acoperire suspect de mare — când acoperirea se apropie de 100%, dar defectele tot nu apar.
- Codul vechi este refactorizat — rezultatele mutațiilor arată dacă testele existente ar detecta o regresie.
- Biblioteci și componente partajate — o defecțiune la o unitate reutilizată component se multiplică pentru fiecare apelant.
- Echipe care se antrenează dezvoltare bazată pe teste — scorul verifică dacă testele scrise mai întâi funcționează cu adevărat.
De obicei, nu merită să rulezi pe prototipuri de unică folosință, pe cod subțire sau generat fără logică de ramificare sau pe suite dominate de algoritmi lenti. teste de integrare care deja durează ore întregi pentru o singură trecere.
Prin urmare, majoritatea echipelor definesc rularea la fișierele modificate, stabilesc un prag pentru modulele importante și permit accesul mai larg. testarea regresiei suita transportă restul ciclul de viață al testării software.



