Gevinster:
- Evne til å forhindre at kunstig intelligens aksepterer feilaktig oppførsel som "riktig" ved å beregne forventet verdi i enhetstester uavhengig av akseptregelen
- Evne til å skrive ut raske, uavhengige og repeterbare tester ved å bruke AAA- og FIRST-prinsipper og håne eksterne avhengigheter
- Evne til å teste tester med mutasjon (kodebrudd) og gjenkjenne vanskelig å teste kode som en designlukt
Det største og raskeste laget i testpyramiden er enhetstesting – testing som verifiserer en funksjon eller en liten kodebit isolert fra alt annet. Tusenvis av enhetstester kjører på sekunder og fanger en feil mens koden fortsatt er på utviklerens skjerm. Kunstig intelligens (AI) er kanskje mest dyktig til å produsere enhetstester: du gir den en funksjon, AI produserer dusinvis av tester. Men nettopp denne bekvemmeligheten gir opphav til den største fellen: AI produserer enkelt tester som "gløder grønt, men som ikke bekrefter noe" eller aksepterer den nåværende (kanskje feilaktige) oppførselen til koden som "riktig". I denne enheten lærer du hvordan du skriver virkelig beskyttende enhetstester med AI og forholdet mellom testbar kode og AI.
Kvaliteter ved en god enhetstest: FØRST
Gode enhetstester følger FØRSTE prinsipper: Rask, Uavhengig (tester skal ikke være avhengige av hverandre), Repeterbare (kan gjentas — samme resultat i alle miljøer), Selvvaliderende (klart bestått/ikke bestått), Rettidig (i tide). Minn deg selv på disse prinsippene når du lar AI produsere tester; be spesielt om at testen ikke er avhengig av omverdenen (faktisk database, nettverk, klokke) for å være "uavhengig" og "repeterbar".
AAA-mønster og uttrykksfull påstand
En solid enhetstest følger AAA-strukturen: Ordne (forbered - sett opp innganger og avhengigheter), Act (utfør - kall funksjonen under test), Bekreft (valider - sammenlign resultatet med forventet verdi). Den kritiske er påstå. Den vanligste feilen AI gjør er å utlede påstanden fra utdataene fra koden som testes - "hva koden returnerer er sant"-logikken. Dette gjør testen meningsløs. Den riktige måten er å bestemme forventet verdi uavhengig (beregn den manuelt fra akseptkriteriene).
OBS: Hvis du forteller AI-en "skriv en test for denne funksjonen", kan AI-en kjøre funksjonen og skrive utdataene som "forventet". Denne testen består selv om funksjonen er falsk. Si i stedet "du beregner de forventede resultatene i henhold til disse reglene, ikke referer til gjeldende utgang av funksjonen."
Spotter, stubber og avhengigheter
Enhetstesting krever isolasjon. Hvis funksjonen din er avhengig av en database eller API, erstattes de med falske objekter (mock/stub — en kontrollert, dummy-erstatning for den virkelige avhengigheten) i testing. Dette gjør testen rask, uavhengig og reproduserbar. AI kan produsere mock installasjon; Men pass deg for overdreven hån: Hvis du håner alt, vil testen bare verifisere "hva hånet returnerer", ikke den faktiske logikken. Balanse: etterlign omverdenen, utfør den virkelige logikken som testes.
Testbarhet og AI
Det er en interessant tilbakemelding: kode som er vanskelig å teste er ofte dårlig utformet kode. Hvis AI har problemer med å skrive tester til en funksjon (for mange avhengigheter, skjult global tilstand, bivirkninger), er det en designlukt. Å spørre AI "hvordan ville du refaktorert denne koden for å gjøre den testbar" fører til både bedre testing og bedre kode.
Parameteriserte tester og datamangfold
Å skrive en separat test hver gang for å verifisere den samme regelen med forskjellige innganger er både kjedelig og vanskelig å opprettholde. Parameterisert testing - en struktur som gjentatte ganger kjører den samme testlogikken på en liste over innganger og forventede resultater - eliminerer denne repetisjonen: en enkelt testkropp mates med dusinvis av inngangspar. AI er veldig effektiv til å produsere disse input-forventede utfallstabellene når du gir den dine akseptregler; Spesielt tar den systematisk opp grenseverdier og ekvivalensklasser.
Men det er en felle her også: AI har en tendens til å utlede de forventede resultatene i den genererte tabellen fra koden som testes. Denne feilen er enda farligere i parameterisert testing, fordi en enkelt feil logikk ugyldiggjør dusinvis av linjer. La derfor alltid kolonnen forventet resultat beregnes uavhengig i henhold til akseptregelen og valider minst noen få rader manuelt. Be også om en beskrivelseskolonne "hva representerer hver rad"; så når en rad bryter, ser du umiddelbart hvilken tilstand som er brutt.
Tips: Legg med vilje til en "felle-rad" i den parameteriserte testtabellen - det vil si, bevisst feilskrive resultatet. Hvis den linjen ikke blir rød når du kjører testen, bekrefter ikke testen faktisk den situasjonen. Dette er en rask mock-pass-sjekk.
Svak forespørsel / Sterk forespørsel
Svak: "Skriv en enhetstest for denne funksjonen."
Sterk: Skriv enhetstester for [språk/rammeverk] for funksjonen taxCalculate(amount, rate). Akseptregel: resultat = beløp * rate, avrundet til 2 desimaler; negativt beløp eller rate gir en feil; returnerer 0 hvis raten er 0. Bruk AAA-struktur. Beregn forventede verdier manuelt i henhold til DISSE gjeldende reglene, og ikke referer til DISSE, negative, negative funksjonene (dekke gjeldende, negative, negative tilfeller). avrund til desimaler). La navnet på hver test beskrive regelen den verifiserer ekstern avhengighet "Nei."
Kraftig ledetekst; Den gir akseptregelen, uavhengig forventet verdiforventning, struktur og kantsaker. Dermed blir testen regelens vokter, ikke speilet av koden.
Kvalitetstabell for enhetstest
symptom
Dårlig test (falsk tillit)
god test
hevde
Ingen eller "ikke null"
Forventet konkret verdi
Forventet verdikilde
Utgang av funksjonen
Akseptregel / manuell beregning
avhengighet
Faktisk DB/nettverk/time
Isolert med mock/stub
kantkasse
Bare lykkelig vei
grense, negativ, feil
Når du bryter koden
forblir grønn
blir rødt
Navn
test1, testmetode
beskriver regelen den bekrefter
Fire kopierbare maler
1) Regeldrevet enhetstesting:
Din rolle: senior programvaretestingeniør. Skriv en enhetstest på følgende funksjon med [språk/rammeverk]: [signatur]. Akseptregler: [regler].- Bruk AAA-struktur.- Beregn forventede verdier manuelt i henhold til DISSE reglene; IKKE referer til gjeldende utgang for funksjonen. - Dekk grensen, negativ, feil og lykkelig vei med separate tester. - La hvert testnavn beskrive regelen den verifiserer. - Hånlig eksterne avhengigheter; Få selve logikken til å fungere.
2) Mutasjonsmotstandskontroll:
Sjekk ut disse enhetstestene. List opp 5 mindre justeringer jeg kan gjøre i koden under test (en - i stedet for en +, en >= i stedet for en >, en grenseforskyvning) og fortell meg for hver av disse testene som blir røde? Hvis ingen returneres, er testen utilstrekkelig. Kode + tester: [lim inn]
3) Testbarhetsgjennomgang:
Hvorfor er det vanskelig å skrive en enhetstest for denne funksjonen? Skjult avhengighet, global status, bivirkninger, er det mange ansvarsområder? Foreslå minimal refactoring for å gjøre det testbart; ikke endre atferd. Kode: [lim inn]
4) Ufullstendig scenariofullføring:
Følgende funksjon og tilgjengelige tester er gitt. List opp hvilken atferd/edgecase som ALDRI har blitt testet (scope gap) og legg til en test for hver. Funksjon+tester: [lim inn]
tre minisaker
Tilfelle 1 – Test speiling av koden. En utvikler fikk AI til å skrive en test for avrundingsfunksjonen; 10 tester var grønne. Faktisk var funksjonen avrundet i feil retning, men AI hadde tatt de forventede verdiene fra funksjonens utgang, så testene anså feilen som "sann". Da de forventede verdiene ble beregnet manuelt med den "regeldrevne" malen, ble 4 tester røde og den virkelige feilen ble avslørt.
Tilfelle 2 — Verdien av mutasjonskontroll. Ett team stolte på 45 enhetstester. Prøvde 20 mindre justeringer av koden med en "mutasjonsrobusthetssjekk"; tester fanget bare 11 av dem. De resterende 9 forstyrrelsene gikk stille. Laget styrket svake tester; En faktisk beregningsfeil ble fanget opp av disse forbedrede testene i neste utgivelse.
Tilfelle 3 - Utestbarhet er en designlukt. AI kunne ikke skrive tester for en bestillingsfunksjon, den trengte konstant den virkelige databasen. Malen "testbarhetsgjennomgang" viste at funksjonen innebygde databasetilgang. Når avhengighetsinjeksjonen ble fjernet, kunne tester skrives og koden ble renere.
Vanlige feil
- Utlede forventet verdi fra kode. AI aksepterer funksjonsutgangen som "riktig"; test som bekrefter feil kode.
- Test uten påstand eller med triviell påstand. "Han gjorde ikke en feil, han bestod" logikk; Det bekrefter ingenting.
- Ekstrem hån. Håner alt og tester bare det hånet returnerer; ekte logikk er ikke testet.
- Bare den lykkelige veien. Omgå grense-, negativ- og feiltilstander.
- Tester ikke ved å knekke koden. Stoler på grønt uten å se etter mutasjoner.
- Ignorerer uprøvebarhet. Ikke gjenkjenne og fikse dårlig design i stedet for å presse hardt.
Oppsummert
Enhetstester er det raskeste og største laget i testpyramiden; Den fanger feilen på det billigste øyeblikket. AI er svært kapabel til å produsere enhetstester, men den største fallgruven er å skrive tester som antar feil oppførsel som "riktig" ved å utlede den forventede verdien fra selve koden. Løsning: gi akseptreglene, få de forventede verdiene beregnet manuelt, håndhev AAA- og FIRST-prinsippene, hån omverdenen og kjør den faktiske logikken, og test hver test ved mutasjon (bryt koden). Kode som er vanskelig å teste er et designskilt som må fikses.
Søknadsoppgave
Velg en funksjon som inneholder en forretningsregel fra ditt eget prosjekt. Skriv godkjenningsregler og få AI til å skrive tester med malen "regeldrevet enhetstesting"; Få de forventede verdiene beregnet manuelt. Bruk deretter "mutasjonsrobusthetssjekken": gjør minst 5 små brudd i koden og mål hvor mange tester som blir røde. Legg til ny test for uoppdagede korrupsjoner. Rapporter hvor mange forstyrrelser som ble fanget (for eksempel mutasjonsscore).
sjekkliste
- [ ] Jeg ga akseptreglene og fikk beregnet de forventede verdiene manuelt.
- [ ] Jeg sørget for at testene ikke hentet den forventede verdien fra koden.
- [ ] Jeg har etablert uavhengig testing etter AAA og FIRST retningslinjer.
- [ ] Jeg hånet de eksterne avhengighetene og kjørte selve logikken.
- [ ] Jeg dekket grense-, negative- og feiltilfeller.
- [ ] Ved å bryte koden (mutasjonen) beviste jeg at testene faktisk beskytter.