Gevinster:
- Evne til at forhindre kunstig intelligens i at acceptere fejlagtig adfærd som 'korrekt' ved at beregne den forventede værdi i enhedstests uafhængigt af acceptreglen
- Evne til at udskrive hurtige, uafhængige og gentagelige tests ved at anvende AAA og FIRST principper og håne eksterne afhængigheder
- Evne til at teste tests med mutation (kodebrud) og genkende svær at teste kode som en designlugt
Det største og hurtigste lag i testpyramiden er enhedstestning - test, der verificerer en funktion eller et lille stykke kode isoleret fra alt andet. Tusindvis af enhedstests kører på få sekunder og fanger en fejl, mens koden stadig er på udviklerens skærm. Kunstig intelligens (AI) er måske mest dygtig til at producere enhedstests: hvis du giver den en funktion, producerer AI snesevis af tests. Men netop denne bekvemmelighed giver anledning til den største fælde: AI producerer nemt tests, der "gløder grønt, men ikke verificerer noget" eller accepterer den aktuelle (måske fejlbehæftede) adfærd af koden som "korrekt". I denne enhed lærer du, hvordan du skriver virkelig beskyttende enhedstest med AI og forholdet mellem testbar kode og AI.
Kvaliteter ved en god enhedstest: FØRST
Gode enhedstests følger FØRSTE principper: Hurtig, Uafhængig (tests bør ikke være afhængige af hinanden), Gentagelige (kan gentages - samme resultat i alle miljøer), Selvvaliderende (klart bestået/ikke bestået), Rettidig (til tiden). Mind dig selv om disse principper, når AI producerer tests; bede specifikt om, at testen ikke afhænger af omverdenen (faktisk database, netværk, ur) for at være "uafhængig" og "gentagelig".
AAA-mønster og udtryksfuld påstand
En solid enhedstest følger AAA-strukturen: Arranger (forbered - opsæt input og afhængigheder), Handl (udfør - kald funktionen under test), Assert (valider - sammenlign resultatet med den forventede værdi). Den kritiske er hævd. Den mest almindelige fejl, AI laver, er at udlede påstanden fra outputtet af koden, der testes - logikken "hvad end koden returnerer, er sand". Dette gør testen meningsløs. Den korrekte måde er at bestemme den forventede værdi uafhængigt (beregn den manuelt ud fra acceptkriterierne).
Bemærk: Hvis du fortæller AI'en "skriv en test for denne funktion", kan AI'en køre funktionen og skrive dens output som "forventet". Denne test består, selvom funktionen er falsk. Sig i stedet "du beregner de forventede resultater i henhold til disse regler, referer ikke til det aktuelle output af funktionen."
Spotter, stubbe og afhængigheder
Enhedstest kræver isolering. Hvis din funktion afhænger af en database eller API, erstattes de med mock-objekter (mock/stub — en kontrolleret, dummy-erstatning for den reelle afhængighed) i test. Dette gør testen hurtig, uafhængig og reproducerbar. AI kan producere mock installation; Men pas på overdreven hån: Hvis du håner alt, vil testen kun bekræfte "hvad hånen returnerer", ikke den egentlige logik. Balance: efterlign omverdenen, udfør den rigtige logik, der testes.
Testbarhed og AI
Der er en interessant feedback: kode, der er svær at teste, er ofte dårligt designet kode. Hvis AI'en har problemer med at skrive test til en funktion (for mange afhængigheder, skjult global tilstand, bivirkninger), er det en designlugt. At spørge AI'en "hvordan ville du omstrukturere denne kode for at gøre den testbar" fører til både bedre test og bedre kode.
Parametriserede tests og datadiversitet
At skrive en separat test hver gang for at verificere den samme regel med forskellige input er både kedeligt og svært at opretholde. Parameteriseret test - en struktur, der gentagne gange kører den samme testlogik på en liste over input og forventede resultater - eliminerer denne gentagelse: et enkelt testlegeme fodres med dusinvis af inputpar. AI er meget effektiv til at producere disse input-forventede udfaldstabeller, når du giver den dine acceptregler; Især tabulerer den systematisk grænseværdier og ækvivalensklasser.
Men der er også en fælde her: AI har en tendens til at udlede de forventede resultater i den genererede tabel fra koden under test. Denne fejl er endnu mere farlig i parameteriseret test, fordi en enkelt forkert logik ugyldiggør snesevis af linjer. Få derfor altid kolonnen med forventet resultat beregnet uafhængigt i henhold til acceptreglen og valider manuelt mindst nogle få rækker. Bed også om en beskrivelseskolonne "hvad repræsenterer hver række"; så når en række går i stykker, ser du med det samme, hvilken tilstand der er brudt.
Tip: Tilføj med vilje en "fælderække" til den parametriserede testtabel - det vil sige, bevidst indtaste resultatet forkert. Hvis den linje ikke bliver rød, når du kører testen, bekræfter din test faktisk ikke denne situation. Dette er en hurtig mock-pass check.
Svag prompt / Stærk prompt
Svag: "Skriv en enhedstest for denne funktion."
Stærk: Skriv [sprog/ramme]-enhedstest for funktionen TaxCalculate(beløb, sats). Acceptregel: resultat = beløb * sats, afrundet til 2 decimaler; negativt beløb eller sats kaster en fejl; returnerer 0, hvis satsen er 0. Brug AAA-struktur. Beregn manuelt forventede værdier i henhold til DISSE, store, negative, negative tilfælde, og referer ikke til de aktuelle, negative tilfælde (0, dæk, negative tilfælde. afrund til decimaler). Lad navnet på hver test beskrive den regel, den verificerer "Nej".
Kraftig prompt; Det giver acceptreglen, uafhængig forventet værdiforventning, struktur og kantsager. Testen bliver således reglens vogter, ikke kodens spejl.
Enhedstest kvalitetstabel
symptom
Dårlig test (falsk tillid)
god test
hævde
Ingen eller "ikke null"
Forventet konkret værdi
Forventet værdikilde
Output af funktionen
Acceptregel / manuel beregning
afhængighed
Faktisk DB/netværk/time
Isoleret med mock/stub
kantkasse
Kun glad vej
grænse, negativ, fejl
Når du knækker koden
forbliver grøn
bliver rød
Navn
test1, testmetode
beskriver den regel, den bekræfter
Fire kopierbare skabeloner
1) Regeldrevet enhedstest:
Din rolle: senior software testingeniør. Skriv en enhedstest på følgende funktion med [sprog/ramme]: [signatur]. Acceptregler: [regler].- Brug AAA-struktur.- Beregn forventede værdier manuelt i henhold til DISSE regler; Henvis IKKE til funktionens aktuelle output. - Dæk grænsen, negativ, fejl og lykkelig vej med separate tests. - Lad hvert testnavn beskrive den regel, den verificerer. - Håne eksterne afhængigheder; Få selve logikken til at fungere.
2) Mutationsmodstandskontrol:
Tjek disse enhedstests. Angiv 5 mindre justeringer, jeg kunne lave til koden under test (en - i stedet for et +, en >= i stedet for en >, en grænseforskydning) og fortæl mig for hver enkelt af disse tests, der bliver rød? Hvis ingen returneres, er testen utilstrækkelig. Kode + test: [indsæt]
3) Testbarhedsgennemgang:
Hvorfor er det svært at skrive en enhedstest for denne funktion? Skjult afhængighed, global status, bivirkninger, er der mange ansvarsområder? Foreslå minimal refactoring for at gøre det testbart; ikke ændre adfærd. Kode: [indsæt]
4) Ufuldstændig scenarieafslutning:
Følgende funktion og tilgængelige test er givet. Angiv hvilken adfærd/edgecase der ALDRIG er blevet testet (scope gap), og tilføj en test for hver. Funktion+test: [indsæt]
tre minisager
Tilfælde 1 — Test afspejling af koden. En udvikler fik AI til at skrive en test for afrundingsfunktionen; 10 tests var grønne. Faktisk rundede funktionen i den forkerte retning, men AI'en havde taget de forventede værdier fra funktionens output, så testene betragtede fejlen som "sand". Da de forventede værdier blev beregnet manuelt med den "regeldrevne" skabelon, blev 4 tests røde, og den reelle fejl blev afsløret.
Tilfælde 2 — Værdien af mutationskontrol. Et hold stolede på 45 enhedstests. Prøvede 20 mindre justeringer af koden med en "mutations robusthed check"; test fangede kun 11 af dem. De resterende 9 forstyrrelser gik stille og roligt. Holdet styrkede svage tests; En faktisk regnefejl blev fanget af disse forbedrede test i næste udgivelse.
Case 3 — Utestbarhed er en designlugt. AI'en kunne ikke skrive test til en bestillingsfunktion, den havde konstant brug for den rigtige database. "Testability review" skabelonen viste, at funktionen indlejrede databaseadgang. Da afhængighedsindsprøjtningen blev fjernet, kunne der skrives test, og koden blev renere.
Almindelige fejl
- Udledning af den forventede værdi fra kode. AI'en accepterer funktionsoutputtet som "korrekt"; test, der bekræfter fejlkode.
- Test uden påstand eller med trivielt påstand. "Han kastede ikke en fejl, han bestod" logik; Det bekræfter ikke noget.
- Ekstrem hån. At håne alt og kun teste, hvad hånen returnerer; ægte logik er ikke testet.
- Bare den glade vej. Omgå grænse, negative og fejltilstande.
- Tester ikke ved at bryde koden. Stoler på grøn uden at tjekke for mutation.
- Ignorerer untestability. Ikke at genkende og rette dårligt design i stedet for at presse hårde tests.
Sammenfattende
Enhedstest er det hurtigste og største lag af testpyramiden; Den fanger fejlen i det billigste øjeblik. AI er meget i stand til at producere enhedstests, men dens største faldgrube er at skrive test, der antager forkert adfærd som "korrekt" ved at udlede den forventede værdi fra selve koden. Løsning: Giv acceptreglerne, få de forventede værdier beregnet manuelt, håndhæv AAA- og FIRST-principperne, hån omverdenen og kør den faktiske logik, og test hver test ved mutation (bryde koden). Kode, der er svær at teste, er et designskilt, der skal rettes.
Ansøgningsopgave
Vælg en funktion, der indeholder en forretningsregel fra dit eget projekt. Skriv acceptregler og få AI til at skrive test med skabelonen "regeldrevet enhedstestning"; Få de forventede værdier beregnet manuelt. Anvend derefter "mutation robustness check": lav mindst 5 små brud i koden og mål, hvor mange tests der bliver røde. Tilføj ny test for ufangne korruptioner. Rapporter, hvor mange forstyrrelser der blev fanget (såsom mutationsscore).
tjekliste
- [ ] Jeg gav acceptreglerne og fik beregnet de forventede værdier manuelt.
- [ ] Jeg sikrede mig, at testene ikke udledte den forventede værdi fra koden.
- [ ] Jeg har etableret uafhængige test efter AAA og FIRST retningslinjer.
- [ ] Jeg hånede de eksterne afhængigheder og kørte selve logikken.
- [ ] Jeg dækkede grænse-, negative- og fejltilfælde.
- [ ] Ved at bryde koden (mutationen) beviste jeg, at testene faktisk beskytter.