Enhet 10 / 11

Falskt förtroende-risk, testkvalitet och mutationstestning: testning av tester

Vinster:

  • Förmåga att känna igen de tre ansiktena av pseudo-tillit (icke-hävdande, självhävdande, trivialt påstående) och använda motgift
  • Förmåga att använda mutationstestning och mutationspoäng som ett mer exakt mått på kvalitet än procentuell täckning med verktyg eller hand
  • Förmåga att positionera AI som ett rött lag mot testning och jaga efter kryphål utan att falla i berömfällan

Kärnan i denna modul är en återkommande varning: en grön lysande testpanel är inte ett bevis på kvalitet. Om dina tester ger dig självförtroende måste du veta om det självförtroendet är verkligt eller falskt. I en tid av artificiell intelligens (AI) är denna fråga mer kritisk än någonsin, eftersom AI är skicklig på att producera flytande, smidiga men ihåliga tester. Falskt förtroende – att tro att programvaran är korrekt eftersom testerna är gröna, när testerna faktiskt inte verifierar någonting – är det farligaste som kan hända ett QA-team; eftersom det inte döljer att det inte finns några fel, utan att du inte kan se felen. Denna enhet samlar valideringsfilosofin för hela modulen i en disciplin: att testa dina tester.

Guldstandarden för att mäta kvaliteten på testning: mutationstestning

Det mest kraftfulla sättet att förstå om ett test faktiskt skyddar eller inte är mutationstestning (mutationstestning - en teknik som producerar avsiktliga små distorsioner/mutationer i källkoden och mäter om testen upptäcker dessa distorsions). Logiken är enkel: om du medvetet bryter koden (gör ett + till -, ett > till >=, ett sant till falskt), bör en bra testsvit fånga upp den korruptionen och bli röd. Om den inte gör det är den störningen en överlevd mutant - så dina tester bevarar faktiskt inte det beteendet.

Mutationspoäng = mutation dödad / total mutation. Ett paket med 90 % linjetäckning kan ha en mutationspoäng på 40 %; Detta indikerar att linjerna fungerar men beteendet är inte verifierat. Mutationspoäng är ett mycket ärligare mått på kvalitet än procentuell täckning.

Tips: Det finns automatiska mutationsverktyg (PIT/Pitest för Java, Stryker för JavaScript/TypeScript, Stryker.NET för .NET, mutmut för Python). Dessa genererar och testar automatiskt hundratals mutationer. Om du inte har ett verktyg är till och med den manuella metoden "bryt koden" ovärderlig för kritiska funktioner.

Pseudoförtroendes tre ansikten och dess motgift

Pseudo-förtroende form

symptom

motgift

Testa utan att hävda

Koden fungerar, ingenting är validerat

Sant påstående i varje test; testa med mutation

självbekräftande test

Förväntat = utmatning av kod

Beräkna förväntat värde oberoende

Trivialt påstående

"inte null", "200 returnerade"

Validera affärsregel/faktiskt resultat

Storleksfel

90% linjer, lågt skydd

Titta på mutationspoängen

Bräcklig testtolerans

"Fast igen, passera"

Grundorsak + deterministisk testning

Använda AI som ett "rött team"

AI kan både generera pseudo-förtroende och vara en kraftfull allierad i att jaga det. Använd AI som ett rött lag mot dina egna tester: fråga "skriv kod som klarar dessa tester men är fel" eller "hitta en subversion som kommer att lura dessa tester." Om AI hittar kryphål i dina tester är dessa kryphål verkliga risker.

Varning: Fråga inte AI:en "Är min testkvalitet bra?" och ta svaret "ja, bra" som en garanti. AI brukar vara snäll. Utmana istället AI till en konkret uppgift: "producera en bugg som klarar dessa tester." Om det kan producera det, är dina tester blinda för det felet.

Motsvarande mutationer och poängens gränser

Mutationstestning är kraftfullt, men det har en hake: vissa mutationer ändrar inte kodens beteende alls. Dessa kallas ekvivalenta mutationer (ekvivalent mutant — korrupt kod, mutation som ger exakt samma resultat som originalet). Till exempel, att ändra initialvärdet för en variabel som aldrig används påverkar inte utdata; Inget test kan och bör inte fånga detta. Därför är en 100 % mutationspoäng ofta ouppnåelig i praktiken och är inte målet. Att rensa bort motsvarande mutationer för hand är arbetsintensivt; Så läs inte mutationspoängen som ett absolut provpoäng, utan som en ärlig indikator på "skyddar verkligen mina tester?"

Det praktiska tillvägagångssättet är detta: istället för att ständigt köra mutationstestning över hela kodbasen, kör den på de moduler som innehåller den högsta risken och de mest komplexa affärsreglerna. Undersök de överlevande mutationerna i dessa moduler en efter en; Om det är en riktig lucka, lägg till ett test; om det är en likvärdig mutation, markera den med motivering och godkänn. AI kan utföra initial screening för att bedöma om en överlevande mutation är likvärdig; men det slutgiltiga beslutet tas av dig som vet vad koden gör.

Varning: Mutationstestning är beräkningsmässigt dyrt (alla relevanta tester körs om för varje mutation). Så en vanlig och rimlig strategi är att schemalägga det som en veckovis eller pre-release djupkontroll för kritiska moduler, snarare än varje sammanslagning.

Svag prompt / Stark prompt

Svag: "Är mina tester tillräckliga?"
Stark: "Aktera som ett rött team för den här funktionen och testsviten. (1) Generera 8 mutationer i koden som kan dödas (operatörssubstitution, gränsförskjutning, konditionsinversion, returvärdessubstitution). (2) För varje mutation, ange vilket av de befintliga testerna som kommer att fånga det och vilka som INTE kommer att fånga det. (3) För varje mutation som överlever, skriv ett nytt test som kan ta död på alla. testar men bryter mot affärsregeln Kod+tester: [klistra in]"

Kraftfull uppmaning; Det positionerar AI som en testbrytande examinator, inte en berömmaskin.

Fyra kopierbara mallar

1) Manuell mutationskontroll:

Generera 8 signifikanta mutationer (mindre avsiktliga störningar) för denna kod: aritmetisk operatorsubstitution, jämförelsegräns (> vs >=), logisk inversion, retur/konstant substitution, villkorshoppning. För varje mutation, förutsäg vilka av de tillgängliga testerna som kommer att fånga den eller inte. Kod+test: [klistra in]

2) Döda den överlevande mutationen:

Följande mutationstestrapport innehåller överlevande (ofångade) mutationer: [lista/rapport]. För varje, skriv ett minimalt test som kommer att döda den mutationen (koden blir röd när den bryts på det sättet). Kommentera vilket beteende testet bekräftar.

3) Röda laget - blodprovet:

Kan du skriva kod som GÅR ALLA följande tester, men bryter mot följande affärsregel: [affärsregel]. Om så är fallet, vilket kryphål i dessa tester tillåter detta? Lägg till testet som stänger kryphålet. Tester: [klistra in]

4) Testkvalitetsinspektion:

Kontrollera denna testsvit för kvalitet. Kryssa för varje test:- Finns det en sann påstående eller är det rekvisita?- Är det förväntade värdet oberoende, härlett från kod?- Verifierar det affärsregeln eller något trivialt? Ge slutligen en uppskattad "true assert score" och de 3 svagaste testerna. Tester: [klistra in]

tre minifodral

Fall 1 — Täckning 92 %, mutationspoäng 38 %. Ett lag förlitade sig på hög täckning. När mutationstestning kördes med Stryker var poängen 38 %: de flesta av de producerade mutationerna överlevde. Detta var ett bevis på att testerna inte körde linjerna och verifierade beteendet. Teamet investerade tre veckor i att testa kvalitet; Mutationspoängen ökade till 81 %, och två riktiga beräkningsfel fångades upp av dessa förstärkta tester i nästa utgåva.

Fall 2 – AI lurade testet. Med en mall för "rött team" bad en expert AI om kod som klarade befintliga tester men som bröt mot rabattregeln. AI:n skrev en kod som alltid gav en rabatt på noll - och alla tester förblev gröna eftersom inga tester verifierade det faktiska rabattvärdet. Glapp sett, riktiga hävdar tillagda.

Fall 3 — Berömfällan. En juniortestare frågade AI:n "Är mina tester bra?" och var lättad över att höra svaret "Mycket omfattande." Hans seniora kollega lät granska samma tester med hjälp av mallen "testkvalitetsrevision"; Det visade sig att 12 av 20 tester var dekor (utan påstående eller skräp). Rätt fråga gav rätt svar.

Vanliga misstag

  • Missar utrymme för kvalitet. Förlitar sig på hög radtäckning och tittar inte på mutationspoängen alls.
  • Litar på AI:s beröm. Frågar "Är dina tester bra?" och betraktar det positiva svaret som en försäkran.
  • Härleda det förväntade värdet från kod. Självverifierande tester som bekräftar felaktig kod.
  • Nöj dig med triviala påståenden. Kontroller som inte validerar den faktiska regeln, som "inte null", "200 returnerade".
  • Ignorera överlevande mutationer. Att ignorera det som inte fångades i mutationsrapporten.
  • Inte ens försöker manuellt mutera kritisk kod. Hoppa över steget "bryt koden och testa" om verktyget inte är tillgängligt.

Sammanfattningsvis

Pseudo-trust tror att programvaran är korrekt eftersom testerna är gröna; medan testerna kanske inte bekräftar någonting. Guldstandarden för att mäta detta är mutationstestning: att medvetet bryta koden och mäta om testerna fångar den. Mutationspoäng är ett mycket ärligare mått på kvalitet än procentuell täckning. AI både producerar pseudo-förtroende och blir ett kraftfullt rött team i jakten på det - fråga "producera en bugg som klarar dessa tester." Testa dina tester: sant påstående, oberoende förväntat värde, validering av affärsregel och dödade mutationer.

Applikationsuppgift

Importera en funktion som innehåller en affärsregel och dess tester från ditt eget projekt. Om möjligt, kör ett mutationsverktyg (Stryker/Pitest/mutmut) och mät mutationspoängen; Om det inte finns något verktyg, generera minst 8 mutationer med mallen "manuell mutationskontroll" och prova dem manuellt. För varje överlevande mutation, skriv ett nytt test med mallen "döda överlevande mutation". Slutligen, med mönstret "röda laget", se om AI kan producera kod som lurar dina tester. Rapportera din start- och slutmutationspoäng (eller fångad/total mutationshastighet).

checklista

  • [ ] Jag utvärderade testkvaliteten efter mutationspoäng, inte täckning.
  • [ ] Jag körde mutationstestning (antingen med verktyg eller manuellt) för kritisk kod.
  • [ ] Jag skrev nya tester för varje överlevande mutation.
  • [ ] Jag använde AI som det röda laget och sökte efter kryphål i mina tester.
  • [ ] Jag tog inte AI:s "dina tester är bra" beröm som en trygghet.
  • [ ] Jag kontrollerade att varje test verifierar det faktiska påståendet, det oberoende förväntade värdet och affärsregeln.