Enota 6 / 11

Generiranje testa enote in možnost testiranja: Robustno testiranje z umetno inteligenco

Dobički:

  • Sposobnost preprečiti, da bi umetna inteligenca sprejela napačno vedenje kot "pravilno" z izračunom pričakovane vrednosti v testih enot neodvisno od pravila sprejemljivosti
  • Sposobnost tiskanja hitrih, neodvisnih in ponovljivih testov z uporabo načel AAA in FIRST ter norčevanja iz zunanjih odvisnosti
  • Sposobnost testiranja testov z mutacijo (razbijanje kode) in prepoznavanja kode, ki jo je težko testirati, kot dišave po dizajnu

Največja in najhitrejša plast testne piramide je testiranje enot – testiranje, ki preverja funkcijo ali majhen kos kode ločeno od vsega drugega. Na tisoče testov enot se izvede v nekaj sekundah in odkrijejo napako, medtem ko je koda še vedno na zaslonu razvijalca. Umetna inteligenca (AI) je morda najbolj spretna pri izdelavi enotnih testov: dodelite ji funkcijo, AI proizvede na desetine testov. Toda ravno to udobje povzroči največjo past: umetna inteligenca zlahka ustvari teste, ki »svetijo zeleno, vendar ničesar ne preverijo« ali sprejmejo trenutno (morda napačno) vedenje kode kot »pravilno«. V tej enoti se boste naučili, kako napisati resnično zaščitne enotne teste z AI in razmerje med kodo, ki jo je mogoče testirati, in AI.

Lastnosti dobrega testa enote: PRVA

Dobri enotni testi sledijo načelom FIRST: hitri, neodvisni (testi ne smejo biti odvisni drug od drugega), ponovljivi (ponovljivi — enak rezultat v katerem koli okolju), samopreverljivi (jasno uspešno/neuspešno), pravočasni (pravočasno). Opomnite se na ta načela, ko naročite AI, da izdeluje teste; izrecno zahtevajte, da test ni odvisen od zunanjega sveta (dejanske baze podatkov, omrežja, ure), da je "neodvisen" in "ponovljiv".

AAA vzorec in izrazna trditev

Trden test enote sledi strukturi AAA: Uredi (pripravi — nastavi vnose in odvisnosti), Deluj (izvedi — pokliči preizkušano funkcijo), Uveljavi (potrdi — primerjaj rezultat s pričakovano vrednostjo). Kritična je trditev. Najpogostejša napaka, ki jo naredi umetna inteligenca, je izpeljava trditve iz izhoda kode, ki se preskuša – logika »kar koli vrne koda, je res«. S tem postane test brez pomena. Pravilen način je, da pričakovano vrednost določite neodvisno (iz meril sprejemljivosti jo izračunajte ročno).

Pozor: če umetni inteligenci rečete "napiši test za to funkcijo", lahko umetna inteligenca zažene funkcijo in zapiše njen izhod kot "pričakovano". Ta preizkus je uspešen, tudi če je funkcija napačna. Namesto tega recite "izračunate pričakovane rezultate v skladu s temi pravili, ne sklicujte se na trenutni rezultat funkcije."

Posnetki, škrbine in odvisnosti

Testiranje enote zahteva izolacijo. Če je vaša funkcija odvisna od baze podatkov ali API-ja, se pri testiranju zamenjajo z lažnimi objekti (mock/stub — nadzorovan, navidezni nadomestek za resnično odvisnost). Zaradi tega je test hiter, neodvisen in ponovljiv. AI lahko ustvari lažno namestitev; Toda pazite se pretiranega norčevanja: če se norčujete iz vsega, bo test preveril samo, "kaj vrne norčevanje", ne pa dejanske logike. Ravnovesje: posnemajte zunanji svet, izvedite resnično logiko, ki jo testirate.

Preizkušljivost in AI

Obstaja zanimiva povratna informacija: koda, ki jo je težko preizkusiti, je pogosto slabo zasnovana koda. Če ima AI težave s pisanjem testov za funkcijo (preveč odvisnosti, skrito globalno stanje, stranski učinki), je to vonj po dizajnu. Vprašanje umetne inteligence "kako bi preoblikoval to kodo, da bi jo bilo mogoče testirati", vodi do boljšega testiranja in boljše kode.

Parametrirani testi in raznolikost podatkov

Vsakič pisanje ločenega testa za preverjanje istega pravila z različnimi vhodi je dolgočasno in težko vzdrževati. Parametrizirano testiranje – struktura, ki večkrat izvaja isto preskusno logiko na seznamu vhodov in pričakovanih rezultatov – odpravlja to ponavljanje: eno samo testno telo se napaja z več desetinami vhodnih parov. Umetna inteligenca je zelo učinkovita pri izdelavi teh tabel pričakovanih rezultatov vnosa, ko ji podate svoja pravila sprejemanja; Zlasti sistematično prikazuje mejne vrednosti in razrede enakovrednosti.

Toda tudi tukaj obstaja past: AI skuša pridobiti pričakovane rezultate v ustvarjeni tabeli iz kode, ki se testira. Ta napaka je še bolj nevarna pri parametriziranem testiranju, ker ena sama nepravilna logika razveljavi na desetine vrstic. Zato imejte stolpec pričakovanih rezultatov vedno izračunan neodvisno v skladu s pravilom sprejemljivosti in ročno preverite vsaj nekaj vrstic. Zahtevajte tudi opisni stolpec "kaj predstavlja vsaka vrstica"; torej, ko se vrstica prekine, takoj vidite, katero stanje je prekinjeno.

Nasvet: namenoma dodajte »prestrezno vrstico« v parametrizirano preskusno tabelo — to pomeni, da zavestno napačno vnesete rezultat. Če se ta vrstica ne obarva rdeče, ko zaženete preizkus, vaš test dejansko ne preverja te situacije. To je hitro lažno preverjanje.

Šibek poziv/močan poziv

Slabo: "Napišite test enote za to funkcijo."
Močno: Napišite teste enote [jezik/ogrodje] za funkcijo "taxCalculate(znesek, stopnja). Pravilo sprejemljivosti: rezultat = znesek * stopnja, zaokroženo na 2 decimalni mesti; negativni znesek ali stopnja vrže napako; vrne 0, če je stopnja 0. Uporabite strukturo AAA. Ročno izračunajte pričakovane vrednosti v skladu s TEMI pravili; ne sklicujte se na trenutni rezultat funkcije. Zajemite vezane in negativne primere (0, negativno, zelo veliko, zaokroženo na decimalke). Naj ime vsakega testa opisuje pravilo, ki ga preverja.

Močan poziv; Podaja pravilo sprejemljivosti, neodvisno pričakovano pričakovano vrednost, strukturo in robne primere. Tako test postane varuh pravila, ne ogledalo kodeksa.

Tabela kakovosti testa enote

simptom

Slab test (lažno zaupanje)

dober test

trditi

Brez ali "ni nič"

Pričakovana konkretna vrednost

Vir pričakovane vrednosti

Izhod funkcije

Pravilo prevzema / ročni izračun

zasvojenost

Dejanski DB/omrežje/uro

Izolirano z mock/stub

robno ohišje

Le srečna pot

meja, negativno, napaka

Ko zlomite kodo

ostane zelena

postane rdeče

Ime

test1, testna metoda

opisuje pravilo, ki ga potrjuje

Štiri predloge za kopiranje

1) Testiranje enote na podlagi pravil:

Vaša vloga: višji inženir za testiranje programske opreme. Napišite test enote za naslednjo funkcijo z [jezik/ogrodje]: [podpis].Pravila sprejemanja: [pravila].- Uporabite strukturo AAA.- Ročno izračunajte pričakovane vrednosti v skladu s TEMI pravili; NE navajajte trenutnega izhoda funkcije. - Pokrijte mejo, negativno, napako in srečno pot z ločenimi testi. - Naj vsako ime testa opisuje pravilo, ki ga preverja. - Izigravanje zunanjih odvisnosti; Naj dejanska logika deluje.

2) Nadzor odpornosti na mutacije:

Oglejte si te teste enot. Naštejte 5 manjših popravkov, ki bi jih lahko naredil na testirani kodi (a - namesto +, >= namesto >, premik meje) in mi za vsakega povejte, KATERI od teh testov se bo obarval rdeče? Če nobena ni vrnjena, je test nezadosten. Koda + testi: [prilepi]

3) Pregled preizkušljivosti:

Zakaj je težko napisati test enote za to funkcijo? Skrita zasvojenost, globalni status, stranski učinki, je veliko odgovornosti? Predlagajte minimalno preoblikovanje, da bo mogoče testirati; ne spreminjajte vedenja. Koda: [prilepi]

4) Nepopoln zaključek scenarija:

Podane so naslednje funkcije in razpoložljivi testi. Navedite, katero vedenje/edgecase še NIKOLI ni bilo preizkušeno (vrzel v obsegu) in dodajte test za vsakega. Funkcija+preizkusi: [prilepi]

trije mini kovčki

1. primer — Preskusno zrcaljenje kode. Razvijalec je dal AI napisati test za funkcijo zaokroževanja; 10 testov je bilo zelenih. Pravzaprav je funkcija zaokroževala v napačno smer, vendar je umetna inteligenca vzela pričakovane vrednosti iz izhoda funkcije, zato so testi menili, da je napaka "resnična". Ko so bile pričakovane vrednosti ročno izračunane s predlogo "na podlagi pravil", so 4 testi postali rdeči in razkrita je bila prava napaka.

Primer 2 – Vrednost nadzora mutacij. Ena ekipa se je zanašala na 45 testov enot. Preizkusil 20 manjših popravkov kode s "preverjanjem robustnosti mutacije"; testi so jih ujeli le 11. Preostalih 9 motenj je minilo tiho. Ekipa je okrepila šibke teste; Ti izboljšani testi so v naslednji izdaji odkrili dejansko napako pri izračunu.

Primer 3 – nepreverljivost je vonj po dizajnu. AI ni mogel napisati testov za funkcijo naročanja, nenehno je potreboval pravo bazo podatkov. Predloga "testability review" je pokazala, da je funkcija vdelala dostop do baze podatkov. Ko je bila odstranjena injekcija odvisnosti, je bilo mogoče pisati teste in koda je postala čistejša.

Pogoste napake

  • Izpeljava pričakovane vrednosti iz kode. AI sprejme izhod funkcije kot "pravilen"; test, ki potrdi napačno kodo.
  • Test brez trditve ali s trivialno trditvijo. "Ni vrgel napake, opravil je" logika; Ničesar ne potrjuje.
  • Ekstremno posmehovanje. Posmehovanje vsemu in preizkušanje samo tistega, kar posmeh vrne; prava logika ni testirana.
  • Le srečna pot. Obhod mejnih, negativnih stanj in stanj napak.
  • Brez testiranja z zlomom kode. Zaupanje v zeleno brez preverjanja mutacije.
  • Ignoriranje nepreverljivosti. Neprepoznavanje in popravljanje slabe zasnove namesto pospešenega testiranja.

Če povzamem

Preizkusi enot so najhitrejši in največji sloj testne piramide; Napako ujame v najcenejšem trenutku. Umetna inteligenca je zelo sposobna izdelati teste enot, vendar je njena največja past pisanje testov, ki predpostavljajo nepravilno vedenje kot "pravilno", tako da pričakovano vrednost izpeljejo iz same kode. Rešitev: podajte pravila sprejemljivosti, ročno izračunajte pričakovane vrednosti, uveljavite načela AAA in FIRST, posmehujte se zunanjemu svetu in zaženite dejansko logiko ter preizkusite vsak test z mutacijo (razbijanje kode). Koda, ki jo je težko preizkusiti, je oblikovni znak, ki ga je treba popraviti.

Aplikacijska naloga

Izberite funkcijo, ki vsebuje poslovno pravilo iz vašega projekta. Napišite pravila sprejemanja in naj AI piše teste s predlogo »testiranje enot na podlagi pravil«; Pričakovane vrednosti naj se izračunajo ročno. Nato uporabite »preverjanje robustnosti mutacije«: naredite vsaj 5 majhnih prelomov v kodi in izmerite, koliko testov postane rdeče. Dodajte nov test za neulovljene poškodbe. Poročajte o tem, koliko motenj je bilo ujetih (kot je rezultat mutacije).

kontrolni seznam

  • [ ] Podal sem pravila sprejemljivosti in dal ročno izračunati pričakovane vrednosti.
  • [ ] Prepričal sem se, da testi ne izpeljejo pričakovane vrednosti iz kode.
  • [ ] Vzpostavil sem neodvisno testiranje po smernicah AAA in FIRST.
  • [] Posmehoval sem se zunanjim odvisnostim in uporabil dejansko logiko.
  • [ ] Pokril sem omejitve, negativne primere in primere napak.
  • [ ] Z razbitjem kode (mutacija) sem dokazal, da testi res ščitijo.