Jedinica 6 / 11

Generisanje jediničnih testova i mogućnost testiranja: robusno testiranje sa AI

Dobici:

  • Sposobnost da se spriječi umjetna inteligencija da prihvati pogrešno ponašanje kao 'ispravno' izračunavanjem očekivane vrijednosti u jediničnim testovima neovisno o pravilu prihvatanja
  • Sposobnost ispisa brzih, nezavisnih i ponovljivih testova primjenom AAA i FIRST principa i ismijavanjem vanjskih ovisnosti
  • Sposobnost testiranja testova s mutacijom (razbijanje koda) i prepoznavanja koda koji se teško testira kao miris dizajna

Najveći i najbrži sloj piramide testiranja je testiranje jedinica — testiranje koje provjerava funkciju ili mali dio koda izolovano od svega ostalog. Hiljade jediničnih testova pokreću se u sekundi i hvataju grešku dok je kod još na ekranu programera. Umjetna inteligencija (AI) je možda najvještija u proizvodnji jediničnih testova: vi joj date funkciju, AI proizvodi desetine testova. Ali upravo ova pogodnost dovodi do najveće zamke: AI lako proizvodi testove koji “svijetle zeleno, ali ništa ne provjeravaju” ili prihvaćaju trenutno (možda pogrešno) ponašanje koda kao “ispravno”. U ovoj cjelini naučit ćete kako pisati istinski zaštitne jedinične testove s AI-om i odnos između provjerljivog koda i AI-a.

Kvalitete dobrog jediničnog testa: PRVO

Dobri jedinični testovi prate FIRST principe: Brzi, Nezavisni (testovi ne bi trebalo da zavise jedan od drugog), Ponovljivi (ponovljivi - isti rezultat u bilo kom okruženju), Samopotvrđujući (jasno prošao/nepao), Pravovremeni (na vreme). Podsjetite se ovih principa kada AI proizvodi testove; posebno zamolite da test ne ovisi o vanjskom svijetu (stvarna baza podataka, mreža, sat) da bude "nezavisan" i "ponovljiv".

AAA obrazac i ekspresivna tvrdnja

Čvrsti jedinični test prati AAA strukturu: Rasporedi (pripremi — postavi ulaze i zavisnosti), postupi (izvrši — pozovi funkciju koja se testira), potvrdi (potvrdi — uporedi rezultat sa očekivanom vrednošću). Kritična je tvrdnja. Najčešća greška koju AI pravi je izvođenje tvrdnje iz izlaza koda koji se testira — logika „šta god kod vrati je istina“. Ovo čini test besmislenim. Ispravan način je da se očekivana vrijednost odredi nezavisno (iz kriterija prihvatljivosti, izračunajte je ručno).

Pažnja: Ako AI kažete da "napiše test za ovu funkciju", AI može pokrenuti funkciju i napisati njen izlaz kao "očekivan". Ovaj test prolazi čak i ako je funkcija lažna. Umjesto toga, recite "očekivane rezultate izračunavate prema ovim pravilima, nemojte upućivati ​​na trenutni izlaz funkcije."

Podsmijeh, zaglavci i ovisnosti

Jedinično testiranje zahtijeva izolaciju. Ako vaša funkcija ovisi o bazi podataka ili API-ju, oni se zamjenjuju lažnim objektima (mock/stub — kontrolirana, lažna zamjena za stvarnu ovisnost) u testiranju. To čini test brzim, nezavisnim i ponovljivim. AI može proizvesti lažnu instalaciju; Ali pazite se pretjeranog ismijavanja: ako se sve rugate, test će samo provjeriti "šta poruga vraća", a ne stvarnu logiku. Balans: oponašajte vanjski svijet, izvršite stvarnu logiku koja se testira.

Testabilnost i AI

Postoji zanimljiva povratna informacija: kod koji je teško testirati je često loše dizajniran kod. Ako AI ima problema s pisanjem testova za funkciju (previše ovisnosti, skriveno globalno stanje, nuspojave), to je miris dizajna. Pitajući AI „kako biste refaktorirali ovaj kod kako biste ga mogli testirati” dovodi do boljeg testiranja i boljeg koda.

Parametrizovani testovi i raznolikost podataka

Pisanje posebnog testa svaki put za provjeru istog pravila s različitim ulazima je i zamorno i teško za održavanje. Parametrizovano testiranje — struktura koja uzastopno pokreće istu logiku testa na listi ulaza i očekivanih rezultata — eliminiše ovo ponavljanje: jedno telo testa se hrani sa desetinama ulaznih parova. AI je veoma efikasna u izradi ovih tabela očekivanih ishoda kada mu date svoja pravila prihvatanja; Konkretno, sistematski tabelarira granične vrijednosti i klase ekvivalencije.

Ali i ovdje postoji zamka: AI teži da izvede očekivane rezultate u generiranoj tabeli iz koda koji se testira. Ova greška je još opasnija u parametriziranom testiranju, jer jedna netočna logika poništava desetine linija. Stoga, uvijek neka se kolona očekivanog rezultata izračuna neovisno u skladu s pravilom prihvaćanja i ručno provjeri barem nekoliko redova. Takođe zatražite kolonu opisa "šta svaki red predstavlja"; tako da kada se red prekine, odmah vidite koje je stanje prekinuto.

Savjet: Namjerno dodajte „red za zamku“ u parametriziranu testnu tablicu – to jest, svjesno pogrešno upišite rezultat. Ako ta linija ne postane crvena kada pokrenete test, vaš test zapravo ne potvrđuje tu situaciju. Ovo je brza provjera prolaska.

Slaba prompt / Jaka prompt

Slabo: "Napišite jedinični test za ovu funkciju."
Jaka: Napišite [jezik/okvir] jedinične testove za funkciju "taxCalculate(amount, rate). Pravilo prihvaćanja: rezultat = iznos * stopa, zaokruženo na 2 decimale; negativan iznos ili stopa daje grešku; vraća 0 ako je stopa 0. Koristite AAA strukturu. Ručno izračunajte očekivane vrijednosti prema OVIM pravilima; nemojte referencirati na trenutni izlaz velike vrijednosti za ovu funkciju (kover 0). zaokružiti na decimale).

Snažan prompt; Daje pravilo prihvatanja, nezavisna očekivana očekivana vrijednost, strukturu i rubne slučajeve. Dakle, test postaje čuvar pravila, a ne ogledalo koda.

Tablica kvaliteta jediničnog testa

simptom

Loš test (lažno povjerenje)

dobar test

tvrditi

Ništa ili "nije null"

Očekivana konkretna vrijednost

Izvor očekivane vrijednosti

Izlaz funkcije

Pravilo prihvatanja / ručni proračun

zavisnost

Stvarni DB/mreža/sat

Izolirano sa mock/stub

rubno kućište

Samo sretan put

granica, negativna, greška

Kada razbijete kod

ostaje zelena

postaje crveno

Ime

test1, testMethod

opisuje pravilo koje potvrđuje

Četiri šablona za kopiranje

1) Jedinično testiranje vođeno pravilima:

Vaša uloga: viši inženjer za testiranje softvera. Napišite jedinični test na sljedećoj funkciji sa [jezikom/okvirom]: [potpisom]. Pravila prihvatanja: [pravila].- Koristite AAA strukturu.- Ručno izračunajte očekivane vrijednosti prema OVIM pravilima; NEMOJTE referencirati trenutni izlaz funkcije. - Pokrijte granicu, negativ, grešku i sretan put posebnim testovima. - Neka svako ime testa opiše pravilo koje potvrđuje. - Ismijavati vanjske zavisnosti; Neka stvarna logika funkcioniše.

2) Kontrola otpornosti na mutacije:

Pogledajte ove jedinične testove. Navedite 5 manjih podešavanja koje bih mogao napraviti u kodu koji se testira (a - umjesto a +, a >= umjesto a >, pomak granice) i recite mi za svaki KOJI će od ovih testova postati crveni? Ako nijedan nije vraćen, test je nedovoljan. Kod + testovi: [zalijepi]

3) Pregled testiranja:

Zašto je teško napisati jedinični test za ovu funkciju? Skrivena ovisnost, globalni status, nuspojave, ima li puno odgovornosti? Predložite minimalno refaktoriranje kako biste ga mogli testirati; ne mijenjajte ponašanje. Šifra: [zalijepi]

4) Nepotpun završetak scenarija:

Date su sljedeće funkcije i dostupni testovi. Navedite koje ponašanje/rubni slučaj NIKAD nije testiran (jaz u opsegu) i dodajte test za svaki. Funkcija+testovi: [zalijepi]

tri mini kofera

Slučaj 1 — Testirajte preslikavanje koda. Programer je dao AI da napiše test za funkciju zaokruživanja; 10 testova je bilo zeleno. Zapravo, funkcija je zaokružila u pogrešnom smjeru, ali AI je uzeo očekivane vrijednosti iz izlaza funkcije, tako da su testovi grešku smatrali "istinitom". Kada su očekivane vrijednosti ručno izračunate sa šablonom "upravljanim pravilima", 4 testa su postala crvena i otkrivena je prava greška.

Slučaj 2 — Vrijednost kontrole mutacija. Jedan tim se oslanjao na 45 jediničnih testova. Isprobao 20 manjih podešavanja koda sa "provjerom robusnosti mutacije"; testovi su uhvatili samo njih 11. Preostalih 9 smetnji je prošlo nečujno. Tim je pojačao slabe testove; Stvarna greška u proračunu je uhvaćena ovim poboljšanim testovima u sljedećem izdanju.

Slučaj 3 — Neprovjerljivost je miris dizajna. AI nije mogao pisati testove za funkciju naručivanja, stalno mu je bila potrebna prava baza podataka. Predložak "testability review" pokazao je da funkcija ima ugrađen pristup bazi podataka. Kada je injekcija zavisnosti uklonjena, testovi su mogli biti napisani i kod je postao čišći.

Uobičajene greške

  • Izvođenje očekivane vrijednosti iz koda. AI prihvaća izlaz funkcije kao "ispravan"; test koji potvrđuje neispravan kod.
  • Testirajte bez tvrdnje ili sa trivijalnom tvrdnjom. "Nije dobacio grešku, prošao je" logiku; To ništa ne potvrđuje.
  • Ekstremno ruganje. Rugati se svemu i testirati samo ono što ismijavanje vraća; prava logika nije testirana.
  • Samo sretan put. Zaobilaženje graničnih, negativnih i grešaka stanja.
  • Ne testirati razbijanjem koda. Vjerovati zelenom bez provjere mutacije.
  • Ignoriranje neprovjerljivosti. Neprepoznavanje i popravljanje lošeg dizajna umjesto napornog testiranja.

Ukratko

Jedinični testovi su najbrži i najveći sloj piramide testiranja; Uhvati grešku u najjeftinijem trenutku. AI je vrlo sposoban za proizvodnju jediničnih testova, ali njegova najveća zamka je pisanje testova koji pretpostavljaju pogrešno ponašanje kao "ispravno" tako što izvode očekivanu vrijednost iz samog koda. Rešenje: dajte pravila prihvatanja, dajte očekivane vrednosti izračunate ručno, primenite AAA i FIRST principe, ismejavajte spoljni svet i pokrenite stvarnu logiku, i testirajte svaki test mutacijom (razbijanjem koda). Kod koji je teško testirati je dizajnerski znak koji treba popraviti.

Zadatak aplikacije

Odaberite funkciju koja sadrži poslovno pravilo iz vašeg vlastitog projekta. Napišite pravila prihvatanja i neka AI napiše testove sa šablonom „testiranje jedinica vođeno pravilima“; Neka očekivane vrijednosti izračunate ručno. Zatim primijenite “provjeru robusnosti mutacije”: napravite najmanje 5 malih prekida u kodu i izmjerite koliko testova postaje crveno. Dodajte novi test za neuhvaćenu korupciju. Prijavite koliko je smetnji uhvaćeno (kao što je rezultat mutacije).

kontrolna lista

  • [ ] Dao sam pravila prihvatanja i ručno izračunao očekivane vrijednosti.
  • [ ] Uvjerio sam se da testovi ne izvode očekivanu vrijednost iz koda.
  • [ ] Uspostavio sam nezavisno testiranje prema AAA i FIRST smjernicama.
  • [ ] Ismijavao sam vanjske zavisnosti i vodio stvarnu logiku.
  • [ ] Pokrio sam limite, negativne i slučajeve grešaka.
  • [ ] Probijanjem koda (mutacijom) dokazao sam da testovi zaista štite.