Hva er mutasjonstesting? (Eksempel)

โšก Smart oppsummering

Mutasjonstesting introduserer bevisst smรฅ feil i kildekoden og kjรธrer deretter den eksisterende testsuiten mot hver feilaktige versjon, for รฅ mรฅle om disse testene er sterke nok til รฅ oppdage endringen.

  • ๐Ÿ”˜ Definisjon: En mutant er programmet som bรฆrer รฉn bevisst syntaktisk endring, og รฅ drepe den beviser at en test oppdaget denne endringen.
  • โ˜‘๏ธ Prosess: Generer mutanter, kjรธr testene mot originalen og mutanten, sammenlign resultater, og styrk deretter testene som ikke fant feil.
  • โœ… Operators: Operand-erstatning, uttrykksmodifikasjon og setningsmodifikasjon produserer de tre hovedfamiliene av mutanter.
  • ๐Ÿงช Score: Mutasjonsscore er prosentandelen av mutanter som er drept, og den mรฅler pรฅstandsstyrke snarere enn bare linjeutfรธrelse.
  • ๐Ÿ› ๏ธ verktรธy: Stryker-deksler JavaManus, TypeScript, C# og Scala, mens PIT muterer JVM-bytekode i Maven og Gradle bygger.
  • โš ๏ธ Kostnad: Hver mutant kjรธrer hele suiten pรฅ nytt, sรฅ mutasjonstesting er treg, dyr og upraktisk uten automatisering.

Mutasjonstesting

Hva er mutasjonstesting?

Mutasjonstesting er en type programvaretesting der visse utsagn i kildekoden endres eller muteres for รฅ sjekke om testtilfellene er i stand til รฅ finne feil i kildekoden. Mรฅlet med mutasjonstesting er รฅ sikre kvaliteten pรฅ testtilfellene nรฅr det gjelder robusthet, slik at de ikke klarer รฅ motstรฅ den muterte kildekoden.

Endringen som gjรธres i et mutantprogram mรฅ holdes ekstremt liten, slik at den ikke pรฅvirker programmets overordnede mรฅl. Mutasjonstesting kalles ogsรฅ en feilbasert teststrategi, fordi den innebรฆrer รฅ bevisst lage en feil i programmet. Det er en form for Hvit Box Testing som hovedsakelig brukes under Enhetstesting.

Mutasjonstesting ble foreslรฅtt i 1971 i en studentartikkel av Richard Lipton og formalisert i artikkelen ยซHints on Test Data Selectionยป fra 1978 av DeMillo, Lipton og Sayward. Den mistet momentum pรฅ grunn av datidens datakostnad og har siden gjenvunnet terreng for sprรฅk som Java, C#, Python, JavaSkript og XML.

Hvordan utfรธre mutasjonstesting?

Fรธlgende er trinnene for รฅ utfรธre mutasjonstesting, ogsรฅ kjent som mutasjonsanalyse:

Trinn 1: Feil introduseres i programmets kildekode ved รฅ opprette mange versjoner kalt mutanter. Hver mutant skal inneholde รฉn enkelt feil, og mรฅlet er รฅ forรฅrsake at mutantversjonen feiler, noe som demonstrerer effektiviteten til testtilfellene.

Trinn 2: Testtilfeller brukes pรฅ det opprinnelige programmet og ogsรฅ pรฅ mutantprogrammet. Testsak skal vรฆre tilstrekkelig, og den er tilpasset for รฅ oppdage feil i et program.

Trinn 3: Sammenlign resultatene fra det opprinnelige og mutantprogrammet.

Trinn 4: Hvis det originale programmet og mutantprogrammet genererer ulik utdata, blir mutanten drept av testtilfellet. Derfor er testtilfellet godt nok til รฅ oppdage endringen mellom det originale og mutantprogrammet.

Trinn 5: Hvis det opprinnelige programmet og mutantprogrammet genererer samme utdata, holdes mutanten i live. I slike tilfeller mรฅ det lages mer effektive testtilfeller som dreper alle mutantene.

Diagrammet nedenfor tracfรธlger de samme fem trinnene, fra det opprinnelige programmet gjennom mutantgenerering til den drepte eller overlevende dommen.

Arbeidsflyt for mutasjonstesting som viser det opprinnelige programmet, genererte mutanter, testutfรธrelse og den drepte eller levende mutantens dom

Hvordan lage mutantprogrammer?

En mutasjon er ikke annet enn en enkelt syntaktisk endring som gjรธres i en programsetning. Hvert mutantprogram skal avvike fra det opprinnelige programmet med nรธyaktig รฉn mutasjon.

Originalt program Mutant program
Hvis (x>y)
Skriv ut "Hei"
Else
Skriv ut "Hei"
Hvis (x
Skriv ut "Hei"
Else
Skriv ut "Hei"

I paret ovenfor er bare sammenligningsoperatoren endret, men et testtilfelle der x er stรธrre enn y skriver nรฅ ut ยซHeiยป i stedet for ยซHalloยป. Illustrasjonen viser den ene syntaktiske redigeringen.

ร‰n syntaktisk endring brukt pรฅ en programsetning for รฅ produsere en enkelt mutant

Hva skal endres i et mutantprogram?

Det finnes flere teknikker som kan brukes til รฅ generere mutantprogrammer. De tre familiene nedenfor dekker de fleste mutasjonsoperatorene som verktรธy leveres med.

Operand erstatningsoperatรธrer Operatorer for modifisering av uttrykk Operatorer for modifisering av setninger
Erstatt operanden med en annen operand (x med y, eller y med x) eller med en konstant verdi. Erstatt en operator, eller sett inn en ny operator, i en programsetning. Programmatiske utsagn er modifisert for รฅ lage mutante programmer.
Eksempel:
If(x>y) erstatte x- og y-verdier
If(5>y) erstatt x med konstant 5
Eksempel:
Hvis(x==y)
Vi kan erstatte == med >= og fรฅ mutantprogrammet som
If(x>=y) og sette inn ++ i setningen
If(x==++y)
Eksempel:
Slett den andre delen i en if-else-setning
Slett hele if-else-setningen for รฅ sjekke hvordan programmet oppfรธrer seg

Noen eksempler pรฅ mutasjonsoperatorer:

  • GOTO etiketterstatning
  • Returerklรฆringserstatning
  • Sletting av erklรฆring
  • Innsetting av unรฆr operator (som โ€“ og ++)
  • Utskifting av logisk kontakt
  • Sammenlignbar erstatning for arraynavn
  • Fjerne else-delen av en if-else-setning
  • Legge til eller erstatte operatorer
  • Erstatning av erklรฆring ved รฅ endre dataene
  • Datamodifisering for variablene
  • Endring av datatyper i programmet

OperaTorer som berรธrer en grensebetingelse overlever oftest, sรฅ mutasjonsresultater peker ofte tilbake pรฅ hull i grenseverdianalyse.

Typer mutasjonstesting

In Engineering programvareMutasjonstesting er grunnleggende kategorisert i tre typer โ€“ utsagnsmutasjon, verdimutasjon og beslutningsmutasjon.

  • Uttalelsesmutasjon โ€“ en setning klippes ut, limes inn eller slettes, sรฅ resultatet kan bli at noen linjer med kode fjernes.
  • Verdimutasjon โ€“ verdiene til primรฆre parametere og konstanter endres, for eksempel endring av en lรธkkegrense eller en terskel.
  • Beslutningsmutasjon โ€“ kontrollsetninger endres, for eksempel flipping en relasjonsoperator eller negerer en betingelse.

Verktรธy grupperer operatorene sine under disse tre overskriftene, slik at familien som produserte en overlevende mutant forteller testeren hvilken type pรฅstand som mangler. En overlevende beslutningsmutant markerer vanligvis en uprรธvd gren, som overlapper med lรธkketesting.

Automatisering av mutasjonstesting

Mutasjonstesting er ekstremt tidkrevende og komplisert รฅ utfรธre manuelt, sรฅ det anbefales รฅ bruke automatiseringsverktรธy, som ogsรฅ reduserer kostnadene. Et mutasjonsverktรธy samler mutantene, planlegger kjรธringene, registrerer hvilken mutant hver mislykkede test drepte, og rapporterer poengsummen.

Liste over tilgjengelige verktรธy:

  • Stryker โ€” et rammeverk for mutasjonstesting med รฅpen kildekode med utgaver for JavaManus og TypeScript (StrykerJS), C# og .NET (Stryker.NET), og Scala (Stryker4s).
  • PIT, ogsรฅ skrevet PITest โ€” et mutasjonstestingssystem for Java og JVM-en som muterer kompilert bytekode og kobles til Maven og Gradle bygger ved siden av JUnit.

Begge kjรธrer som et byggesteg, sรฅ de hรธrer hjemme i samme kontinuerlig integrering rรธrledningen som resten av automatiseringstesting pรฅ.

Mutasjonspoeng

Mutasjonsskรฅren er definert som prosentandelen drepte mutanter av det totale antallet mutanter.

Mutasjonspoeng = (drepte mutanter / totalt antall mutanter) * 100

Formelen vises nedenfor i den formen de fleste verktรธy rapporterer den.

Mutasjonspoengformel som deler drepte mutanter med det totale antallet mutanter og multipliserer med hundre

Testtilfeller beskrives som mutasjonstilstrekkelige nรฅr poengsummen nรฅr 100 prosent. I praksis mรฅ nevneren ekskludere ekvivalente mutanter โ€” mutanter hvis endrede syntaks oppfรธrer seg nรธyaktig som originalen, slik at ingen test kan drepe dem. Verktรธy rapporterer derfor drepte mutanter delt pรฅ drepte pluss overlevende ikke-ekvivalente mutanter, og lar testeren flagge ekvivalenter.

Eksperimentelle resultater har vist at mutasjonstesting er en effektiv mรฅte รฅ mรฅle tilstrekkeligheten av testtilfeller. Den stรธrste ulempen er kostnaden ved รฅ generere mutantene og utfรธre hvert testtilfelle mot hver enkelt.

Mutasjonstesting vs. Code Dekning

Hรธyt testdekning beviser ikke sterke tester. Linje- og grendekning registrerer hvilke utsagn som ble kjรธrt, ikke om noe ble verifisert etterpรฅ, sรฅ en test som kaller en metode og ikke hevder noe teller fortsatt som dekket. Mutasjonstesting tetter dette gapet, fordi en mutant bare dรธr nรฅr en pรฅstand faktisk mislykkes.

Aspekt Code dekning Mutasjonspoengsum
Hva den mรฅler Hvilke linjer eller grener testene ble utfรธrt Hvilke injiserte feil testene oppdaget
Fรธlsom for pรฅstander Nei โ€“ en test med null pรฅstander gir fortsatt dekning Ja โ€“ en mutant overlever nรฅr ingen pรฅstand feiler
Kostnaden for en lรธpetur ร‰n instrumentert testkjรธring ร‰n testkjรธring per overlevende mutant, sรฅ langt tregere
Typisk bruk En rask gate pรฅ hver commit En grundigere periodisk kontroll av kritiske moduler
Feil modus 100 prosent dekning uten reell verifisering Ekvivalente mutanter som aldri kan drepes

De to mรฅlingene er komplementรฆre. Dekningen navngir koden som aldri ble nรฅdd; mutasjonspoengsummen navngir den nรฅdde koden som aldri ble sjekket. Begge gir samme informasjon. prosess for feilhรฅndtering, sammen med tiltak som defekttetthet.

Fordeler med mutasjonstesting

Fรธlgende er fordelene med mutasjonstesting:

  • Det er en kraftig tilnรฆrming for รฅ oppnรฅ hรธy dekning av kildeprogrammet.
  • Den tester selve testsuiten, noe ingen andre teknikk for programvaretesting gjรธr direkte.
  • Mutasjonstesting gir programvareutvikleren et godt nivรฅ av feildeteksjon.
  • Metoden avdekker uklarheter i kildekoden og har kapasitet til รฅ avdekke feil som vanlige kjรธringer aldri nรฅr.
  • Overlevende mutanter er handlingsrettede: hver av dem navngir en spesifikk linje og en spesifikk endring som suiten ikke la merke til.
  • Kunder drar nytte av denne testingen ved รฅ motta et mer pรฅlitelig og stabilt system.

Ulemper med mutasjonstesting

Pรฅ den annen side er fรธlgende ulemper med mutasjonstesting:

  • Mutasjonstesting er ekstremt kostbart og tidkrevende, fordi et stort antall mutantprogrammer mรฅ genereres og kompileres.
  • Siden det er tidkrevende, er det rimelig รฅ si at denne testingen ikke kan gjรธres uten et automatiseringsverktรธy.
  • Hver mutant utรธves av samme antall testtilfeller som det opprinnelige programmet, sรฅ en stor mutantpopulasjon mรฅ kjรธres mot hele testsuiten.
  • Ekvivalente mutanter kan ikke drepes av noen test, og รฅ skille dem fra ekte overlevende krever vanligvis manuell gjennomgang.
  • Fordi metoden endrer kildekoden, er den ikke anvendelig for Svart Box Testing.

Nรฅr man skal bruke mutasjonstesting

Kostnadsprofilen ovenfor betyr at mutasjonstesting sjelden kjรธres over en hel kodebase pรฅ hver commit. Det betaler seg selv der en uoppdaget feil er dyr og koden som testes er liten nok til รฅ mutere raskt.

  • Sikkerhetskritisk eller รธkonomisk logikk โ€” betalingsberegning, skatteregler og autorisasjonskontroller, der et stille feil svar er verre enn et krasj.
  • Suiter med mistenkelig hรธy dekning โ€” nรฅr dekningen er nรฆr 100 prosent, men feilene fortsatt slippes unna.
  • Eldre kode blir refaktorert โ€” mutasjonsresultater avslรธrer om de eksisterende testene ville fange opp en regresjon.
  • Biblioteker og delte komponenter โ€” en feil i en gjenbrukt komponent multipliseres pรฅ tvers av hver innringer.
  • Lag som รธver testdrevet utvikling โ€” poengsummen kontrollerer at testene som ble skrevet fรธrst gjรธr et ordentlig arbeid.

Det er vanligvis ikke verdt รฅ kjรธre pรฅ engangsprototyper, pรฅ tynt lim eller generert kode uten forgreningslogikk, eller pรฅ pakker dominert av trege integrasjonstester som allerede tar timer for รฉn passering.

De fleste teamene skal derfor avgrense kjรธringen til endrede filer, sette en terskel for modulene som er viktige, og la det bredere Regresjonstesting suiten bรฆrer resten av livssyklus for programvaretesting.

Spรธrsmรฅl og svar

En ekvivalent mutant er en endring som endrer syntaksen, men ikke oppfรธrselen, for eksempel รฅ erstatte en lรธkkegrense som aldri nรฅs. Ingen test kan drepe den, sรฅ den mรฅ flagges og ekskluderes fรธr poengsummen er klarert.

Det finnes ikke noe universelt tall. Team setter vanligvis en hรธy terskel for kritiske moduler som betaling eller sikkerhetslogikk, og en lavere andre steder. ร… jage en prosentandel er mindre nyttig enn รฅ gjennomgรฅ hver overlevende mutant i hรธyrisikokode.

Det er de to antagelsene teknikken hviler pรฅ. Den fรธrste sier at programmerere skriver nesten korrekt kode, sรฅ reelle feil er smรฅ. Den andre sier at tester som fanger opp smรฅ feil ogsรฅ fanger opp de komplekse feilene som er bygget opp fra dem.

Begrens mutasjon til filer som er endret i gjeldende gren, bruk dekningsdata pรฅ nytt slik at bare tester som berรธrer en mutant utfรธres, kjรธr mutanter parallelt, og mislykkes byggingen pรฅ et poengsumfall i stedet for et absolutt tall.

Maskinlรฆringsmodeller forutsier hvilke mutanter som sannsynligvis vil overleve, slik at kjรธringen kan trimmes, klassifisere sannsynlige ekvivalente mutanter for gjennomgang, og generere mutanter som ligner feil sett i prosjekthistorikken i stedet for ensartede operatorbytter.

Ja, for den mekaniske delen. Gitt en overlevende mutant og metoden som testes, utarbeider Copilot den manglende pรฅstanden eller kanttilfelletesten. En anmelder mรฅ fortsatt bekrefte at den forventede verdien er korrekt og ikke bare kopiert fra gjeldende oppfรธrsel.

Den reviderer resultatet. Testdrevet utvikling produserer tester fรธr kode, men ingenting garanterer at disse testene bekrefter nok. En periodisk mutasjonskjรธring pรฅ de samme modulene viser om den rรธd-grรธnne syklusen produserte tester som virkelig mislykkes pรฅ et feil svar.

Nei. Feilinjeksjon รธdelegger kjรธretidsmiljรธet og fuzz testing mater feilformede input, som begge bedรธmmer applikasjonen. Mutasjonstesting endrer kildekoden og bedรธmmer testsuiten, slik at objektet som evalueres er annerledes.

Oppsummer dette innlegget med: