Eenheid 6 / 11

Testgeneratie met kunstmatige intelligentie: eenheids-, interface- en automatiseringstests

Winst:

  • Mogelijkheid om unit-, integratie- en UI-tests te produceren met kunstmatige intelligentie in overeenstemming met de testpiramide en zowel limiet- en foutsituaties als gelukkige scenario's te dekken
  • Mogelijkheid om lege/nutteloze tests en opgeblazen berichtgeving uit te bannen door te controleren of elke gegenereerde test daadwerkelijk een gedrag valideert
  • Ervoor zorgen dat de test de bug opmerkt en voorkomt dat de bug wordt opgelost door de AI te vertellen wat de code moet doen

Code schrijven is het halve werk; Bewijzen dat de code correct werkt, is de andere helft. Mobiele apps komen honderden verschillende apparaten, schermformaten, besturingssysteemversies en gebruikersgedrag tegen. Het is onmogelijk om deze allemaal handmatig te testen; Daarom is geautomatiseerd testen (code testen van code – testen dat wordt uitgevoerd zonder een menselijke klik) de ruggengraat van mobiele kwaliteit. AI is ongelooflijk efficiënt in het schrijven van tests, omdat het schrijven van tests precies het soort patroonwerk is waar het van houdt: het valideren van specifiek gedrag voor specifieke invoer. In deze unit leren we hoe we het testen van eenheden, interfacetesten en automatisering met AI kunnen versnellen, maar de kwaliteit van de test door menselijke ogen kunnen garanderen.

Testpiramide: wat te testen en hoeveel

Een gezonde teststrategie lijkt op een piramide. De basis omvat een groot aantal unit-tests (snel testen waarbij een enkele functie of klasse afzonderlijk wordt getest); ze zijn snel en goedkoop. In het midden bevinden zich minder integratietesten (testen hoe meerdere onderdelen samenwerken). Bovenaan vindt u minimale UI/end-to-end-testen (testen gebeurt door op het scherm te klikken zoals de gebruiker doet); ze zijn realistisch, maar langzaam en fragiel. AI helpt op elke laag, maar de meeste waarde ligt aan de basis: het snel produceren van unit-tests van bedrijfslogica.

Testtype

Reikwijdte

snelheid

AI-efficiëntie

testen van eenheden

Enkele functie/klasse

erg snel

zeer hoog

integratie

tussenlaag

middelmatig

hoog

UI / end-to-end

Alle schermstreams

langzaam

Middelmatig (breekbaar)

Tip: Wanneer u de AI vertelt om "tests voor deze functie te genereren", vraag dan expliciet om randgevallen: lege invoer, nul, negatief getal, zeer grote waarde, netwerkfout. AI produceert gemakkelijk een gelukkig pad; De echte fouten verbergen zich in de grenzen en springen eruit als je ze daar niet wilt hebben.

Stappen voor het schrijven van tests met AI

  1. Definieer het te testen gedrag. "Deze functie moet deze uitvoer aan deze invoer geven."
  2. Specificeer het raamwerk. JUnit + MockK op Android, XCTest op iOS, Espresso (Android) of XCUITest (iOS) voor UI.
  3. Vraag naar grenstoestanden. Gelukkig scenario + fout + breekpunten.
  4. Beheer nepobjecten. Externe afhankelijkheden zoals netwerk en database worden geëmuleerd voor testen (mock – gecontroleerde mock in plaats van de daadwerkelijke service).
  5. Voer de test uit en verifieer. Slaagt de test, bevestigt deze iets echt betekenisvols?

De vijfde stap is van cruciaal belang. AI levert soms nutteloze tests op die ‘altijd slagen’; bijvoorbeeld een test die niets verifieert of zijn eigen nepgegevens controleert. Een geslaagde test en een waardevolle test zijn verschillende dingen.

Let op: het feit dat de AI kan produceren, betekent niet dat de test correct is. Soms accepteert de AI het huidige (misschien gebrekkige) gedrag van de code als "correct" en schrijft dienovereenkomstig tests. Dergelijke tests repareren de bug in plaats van deze op te vangen. Jij bepaalt wat de test verwacht; Vertel de AI wat hij moet doen, niet wat de code doet.

Testdekkingsmaatstaf en denkfout

Testdekking (welk percentage van de code wordt uitgevoerd door tests) is een nuttige maar misleidende maatstaf. 90% dekking geeft aan dat 90% van de code is uitgevoerd; maar er is niet geverifieerd dat deze lijnen correct werken. Een test waarbij een lijn wordt uitgevoerd en het resultaat niet wordt gecontroleerd, vergroot de reikwijdte, maar biedt geen zekerheid. Het doel is niet hoge cijfers, maar betekenisvolle validatie. Je kunt snel opschalen met AI, maar zorg ervoor dat elke test ook daadwerkelijk gedrag test.

drie minikoffers

Geval 1 — Grenssituatie vastgelegd. Er werd AI gevraagd om tests uit te voeren voor een geldoverdrachtfunctie in een bankapplicatie, en er werden specifiek ‘negatief bedrag’- en ‘meer dan saldo’-scenario’s toegevoegd. Uit de test bleek dat de overboeking niet met een negatief bedrag geblokkeerd was; dit zou een groot beveiligingsprobleem in de productie zijn. Gesloten door het toevoegen van een éénregelige bediening. Les: grenstoetsen zijn de meest waardevolle toetsen.

Geval 2 — Valse test. Eén team was opgelucht toen ze de dekking konden vergroten tot 85% met 40 door AI geproduceerde eenheidstests. Tijdens de inspectie bleek dat de meeste tests feitelijk geen enkele uitvoer controleerden, ze riepen gewoon de functie aan en schreven assertTrue(true). De dekking was hoog, maar de bescherming was nul. Tests werden gereviseerd en herschreven met echte validaties. Les: dekkingscijfers kunnen liegen.

Geval 3 – UI-testen versneld. Een e-commerceteam schreef in 20 minuten een XCUITest-script van de add-to-cart-stroom met AI; Als het met de hand zou worden geschreven, zou het een halve dag duren. AI raadde schermelement-ID's; Het team matchte ze met de echte code en repareerde ze. Conceptsnelheid is reëel, maar identificatieverificatie is mensenwerk.

Zwakke prompt/sterke prompt

Zwakke prompt: "Schrijf een test voor deze functie."

Krachtige prompt: "Maak eenheidstests voor deze Kotlin-functie met JUnit5 + MockK. Functie: geldoverdracht (bedrag, bron, doel). Te testen gedrag (wat de code zou moeten DOEN): - Geldige overdracht moet succesvol zijn - Negatief of nulbedrag moet worden afgewezen - Bedrag groter dan het saldo moet worden afgewezen - Netwerkfout moet de juiste uitzondering genereren. Elke test moet slechts één ding verifiëren, hun namen moeten beschrijvend zijn, de externe service bespotten. Schrijf geen lege bewering. "

Kopieerbare sjablonen

Eenheidstestsjabloon: "Genereer [JUnit/XCTest] eenheidstests voor deze functie voor [taal]. Verwacht gedrag: [wat te doen]. Inclusief: gelukkig scenario, null-invoer, breekpunten, foutgeval. Laat elke test afzonderlijk gedrag verifiëren; gebruik zinvolle beweringen; bespottelijk. [code]"

UI-testsjabloon: "Schrijf een UI-test van de volgende stroom met [Espresso/XCUITest]: [gebruikersstroom stap voor stap]. Selecteer schermelementen met toegankelijkheids-ID, gebruik id in plaats van tekst. Voeg wachtstrategie toe. Herinner me eraan de element-ID's te matchen met de daadwerkelijke code."

Testauditsjabloon: "Onderzoek deze tests: 1) Verifiëren ze daadwerkelijk een output/gedrag of zijn ze nul? 2) Bestrijken ze grensgevallen? 3) Repareren ze de code met bugs of verwachten ze correct gedrag? Markeer en versterk zwakke tests. [tests]"

Sjabloon voor dekkingsoptimalisatie: "Identificeer niet-geteste delen van deze klasse en stel zinvolle tests voor. Geef prioriteit aan paden met een reëel risico, niet alleen het aantal dekkingen. [code]"

Veel voorkomende fouten

  • Even het gelukkige scenario testen. Fouten worden opgeslagen in grenstoestanden; Vraag er openlijk naar.
  • Een lege/nutteloze test accepteren. Tests van het type assertTrue(true) vergroten de reikwijdte en bieden geen bescherming.
  • Door de AI te laten verifiëren wat de code doet. Testen zou moeten verwachten wat de code zou moeten doen; anders wordt de bug opgelost.
  • Het scoopnummer voor dit doel verwarren. 90% dekking betekent niet 90% nauwkeurigheid.
  • Koppelen naar tekst bij UI-testen. De test wordt verbroken als de tekst verandert; Gebruik een stabiele identificatie (ID).
  • Mocks verkeerd instellen. De ‘eenheidstest’ die de daadwerkelijke service aanroept, zal langzaam en broos zijn.

Samengevat

Testen is de ruggengraat van mobiele kwaliteit, en AI is zeer efficiënt op dit gebied, vooral bij het testen van eenheden. Volg de testpiramide: veel eenheden, gemiddelde integratie, weinig UI-testen. Vraag de AI expliciet naar het gelukkige scenario en beperk gevallen en foutpaden. Zorg ervoor dat elke gegenereerde test daadwerkelijk een gedrag valideert; Lege tests en opgeblazen dekking zijn misleidend. Het belangrijkste is dat u de AI vertelt wat de code moet doen, en niet wat deze doet, zodat de test de bug opspoort en niet repareert.

Applicatie taak

Vraag tests aan bij de AI met behulp van de “Unit test template” voor een bedrijfslogische functie (bijvoorbeeld kortingsberekening of formuliervalidatie) en specificeer expliciet grensgevallen (null, negatief, te groot). Voer de gegenereerde tests uit en laat dezelfde tests vervolgens auditeren met de "Testauditsjabloon". Zoek ten minste één zwakke test, versterk deze en test of de tests een daadwerkelijke fout van de functie opsporen (door een kleine bug toe te voegen).

controlelijst

  • [ ] Ik heb de juiste laag voor de testpiramide geselecteerd (prioriteiteenheid)
  • [ ] Ik wilde naast het gelukkige scenario limiet- en foutgevallen
  • [ ] Ik heb geverifieerd dat elke test een betekenisvolle bewering bevat
  • [ ] Ik vertelde de AI wat de code zou moeten doen, niet wat hij doet
  • [ ] Ik concentreerde me op de daadwerkelijke risicopaden, niet op het aantal dekkingen
  • [ ] Ik heb een stabiele identificatie gebruikt in UI-tests, ik was niet gebonden aan tekst