Unità 6 / 11

Generazione di test con intelligenza artificiale: test di unità, interfaccia e automazione

Guadagni:

  • Capacità di produrre test unitari, di integrazione e UI con intelligenza artificiale in conformità con la piramide di test e coprire situazioni limite ed errori nonché scenari felici
  • Capacità di eliminare i test vuoti/inutili e la copertura gonfia verificando che ogni test generato convalidi effettivamente un comportamento
  • Garantire che il test rilevi il bug e gli impedisca di risolverlo dicendo all'IA cosa dovrebbe fare il codice

Scrivere codice è metà del lavoro; Dimostrare che il codice funziona correttamente è l'altra metà. Le app mobili incontrano centinaia di dispositivi, dimensioni dello schermo, versioni del sistema operativo e comportamenti degli utenti diversi. È impossibile testarli tutti manualmente; Ecco perché i test automatizzati (codice di test del codice, test che viene eseguito senza clic umano) sono la spina dorsale della qualità mobile. L’intelligenza artificiale è incredibilmente efficiente nella scrittura dei test perché scrivere test è esattamente il tipo di lavoro che preferisce: convalidare un comportamento specifico per input specifici. In questa unità impareremo come accelerare i test unitari, i test di interfaccia e l'automazione con l'intelligenza artificiale, garantendo però la qualità del test attraverso gli occhi umani.

Piramide dei test: cosa testare e quanto

Una sana strategia di test assomiglia a una piramide. La base include un gran numero di unit test (test rapidi che testano una singola funzione o classe isolatamente); sono veloci ed economici. Nel mezzo ci sono meno test di integrazione (testare come più parti lavorano insieme). Nella parte superiore è presente un test UI/end-to-end minimo (test eseguito facendo clic sullo schermo come fa l'utente); sono realistici ma lenti e fragili. L’intelligenza artificiale aiuta a ogni livello, ma il valore maggiore è alla base: produrre rapidamente test unitari della logica aziendale.

Tipo di prova

Ambito

velocità

Efficienza dell'intelligenza artificiale

test unitari

Singola funzione/classe

molto veloce

molto alto

integrazione

interstrato

medio

alto

Interfaccia utente/end-to-end

Tutto lo streaming dello schermo

lento

Medio (fragile)

Suggerimento: quando si dice all'IA di "generare test per questa funzione", chiedere esplicitamente i casi limite: input vuoto, null, numero negativo, valore molto grande, errore di rete. L’intelligenza artificiale produce facilmente un percorso felice; I veri errori si nascondono nei confini e saltano fuori se non li vuoi lì.

Passaggi di scrittura dei test con l'intelligenza artificiale

  1. Definire il comportamento da testare. "Questa funzione dovrebbe fornire questo output a questo input."
  2. Specificare il quadro. JUnit + MockK su Android, XCTest su iOS, Espresso (Android) o XCUITest (iOS) per UI.
  3. Richiedi stati limite. Scenario felice + errore + punti di interruzione.
  4. Gestisci oggetti finti. Le dipendenze esterne come la rete e il database vengono emulate per i test (finto: finto controllato invece del servizio vero e proprio).
  5. Esegui il test e verifica. Il test passa, conferma qualcosa di veramente significativo?

Il quinto passo è fondamentale. L’intelligenza artificiale a volte produce test inutili che “superano sempre”; ad esempio, un test che non verifica nulla o controlla i propri dati falsi. Un test positivo e un test valido sono cose diverse.

Attenzione: solo perché l'IA può produrre non significa che il test sia corretto. A volte l'intelligenza artificiale accetta il comportamento attuale (forse difettoso) del codice come "corretto" e scrive i test di conseguenza. Tali test risolvono il bug anziché rilevarlo. Sei tu a determinare cosa si aspetta il test; Di' all'IA cosa dovrebbe fare, non cosa fa il codice.

Misura di copertura del test e fallacia

La copertura dei test (quale percentuale di codice viene eseguita dai test) è una metrica utile ma fuorviante. Una copertura del 90% indica che il 90% del codice è stato eseguito; ma non è stato verificato che quelle linee funzionino correttamente. Un test che esegue una riga e non controlla il risultato gonfia l'ambito ma non fornisce sicurezza. L’obiettivo non sono numeri elevati, ma una validazione significativa. Puoi espanderti rapidamente con l'intelligenza artificiale, ma assicurati che ogni test testi effettivamente un comportamento.

tre mini custodie

Caso 1: situazione frontaliera rilevata. All'intelligenza artificiale è stato chiesto di testare una funzione di trasferimento di denaro in un'applicazione bancaria e in particolare sono stati aggiunti gli scenari "importo negativo" e "più del saldo". Dal test è emerso che il bonifico non è stato bloccato con importo negativo; questa rappresenterebbe una grave vulnerabilità della sicurezza nella produzione. Chiuso aggiungendo un controllo di una riga. Lezione: i test di confine sono i test più preziosi.

Caso 2 – Test falso. Un team è stato sollevato dall'aumentare la copertura all'85% con 40 test unitari prodotti dall'intelligenza artificiale. Durante l'ispezione, si è visto che la maggior parte dei test in realtà non verificava alcun output, chiamavano semplicemente la funzione e scrivevano assertTrue(true). La copertura era alta ma la protezione era zero. I test sono stati revisionati e riscritti con convalide reali. Lezione: i numeri di copertura possono mentire.

Caso 3: test dell'interfaccia utente accelerati. Un team di e-commerce ha scritto uno script XCUITest del flusso di aggiunta al carrello con l'intelligenza artificiale in 20 minuti; Se fosse scritto a mano, ci vorrebbe mezza giornata. Identificatori degli elementi dello schermo indovinati dall'intelligenza artificiale; Il team li ha abbinati al codice reale e li ha corretti. La velocità della bozza è reale, ma la verifica dell'identificatore è un lavoro umano.

Prompt debole / Prompt forte

Prompt debole: "Scrivi un test per questa funzione."

Prompt potente: "Produci test unitari per questa funzione Kotlin con JUnit5 + MockK. Funzione: trasferimento di denaro (importo, origine, destinazione). Comportamenti da testare (cosa dovrebbe FARE il codice): - Il trasferimento valido deve avere successo - L'importo negativo o zero deve essere rifiutato - L'importo maggiore del saldo deve essere rifiutato - L'errore di rete deve generare un'eccezione appropriata Ogni test dovrebbe verificare solo una cosa, i loro nomi dovrebbero essere descrittivi, deridere il servizio esterno. Non scrivere un'asserzione vuota."

Modelli copiabili

Modello di test unitario: "Genera test unitari [JUnit/XCTest] per questa funzione per [linguaggio]. Comportamento previsto: [cosa fare]. Include: scenario felice, input nullo, punti di interruzione, caso di errore. Lascia che ogni test verifichi un singolo comportamento; usa un'asserzione significativa; mock. [codice]"

Modello di test dell'interfaccia utente: "Scrivi un test dell'interfaccia utente del seguente flusso con [Espresso/XCUITest]: [flusso utente passo dopo passo]. Seleziona gli elementi dello schermo con ID di accessibilità, utilizza ID al posto del testo. Aggiungi strategia di attesa. Ricordami di abbinare gli ID degli elementi al codice effettivo."

Modello di audit del test: "Esamina questi test:1) Verificano effettivamente un output/comportamento o sono nulli?2) Coprono casi limite?3) Correggono bug nel codice o si aspettano un comportamento corretto? Segnala e rafforza i test deboli. [test]"

Modello di ottimizzazione della copertura: "Identifica le parti non testate di questa classe e suggerisci test significativi. Dai la priorità ai percorsi con rischio reale, non solo al numero di coperture. [codice]"

Errori comuni

  • Sto solo testando lo scenario felice. Gli errori vengono memorizzati negli stati limite; Chiedeteli apertamente.
  • Accettare un test vuoto/inutile. I test del tipo assertTrue(true) gonfiano l'ambito e non forniscono alcuna protezione.
  • Chiedere all'intelligenza artificiale di verificare cosa sta facendo il codice. I test dovrebbero aspettarsi cosa dovrebbe fare il codice; altrimenti risolve il bug.
  • Confondere il numero dell'ambito per lo scopo. Una copertura del 90% non significa una precisione del 90%.
  • Collegamento al testo nei test dell'interfaccia utente. Il test viene interrotto quando il testo cambia; Utilizza identificatore stabile (id).
  • Impostazione errata dei mock. Il "test unitario" che chiama il servizio vero e proprio sarà lento e fragile.

In sintesi

I test sono la spina dorsale della qualità mobile e l’intelligenza artificiale è molto efficiente in quest’area, soprattutto negli unit test. Segui la piramide dei test: molte unità, integrazione media, pochi test dell'interfaccia utente. Chiedi esplicitamente all'IA lo scenario felice, nonché i casi limite e i percorsi di errore. Assicurarsi che ogni test generato convalidi effettivamente un comportamento; I test vuoti e la copertura gonfiata sono fuorvianti. La cosa più importante è dire all'IA cosa dovrebbe fare il codice, non cosa fa, in modo che il test rilevi il bug e non lo risolva.

Compito dell'applicazione

Richiedi test all'IA utilizzando il "modello di test unitario" per una funzione di logica aziendale (ad esempio calcolo dello sconto o convalida del modulo) e specifica esplicitamente i casi limite (nullo, negativo, troppo grande). Eseguire i test generati, quindi sottoporre gli stessi test ad audit con il "Modello di audit del test". Trova almeno un test debole, rafforzalo e verifica se i test rilevano un errore effettivo della funzione (aggiungendo un piccolo bug).

lista di controllo

  • [ ] Ho selezionato il livello appropriato per la piramide di test (unità prioritaria)
  • [ ] Volevo casi limite ed errori oltre allo scenario felice
  • [ ] Ho verificato che ogni test contenga un'asserzione significativa
  • [] Ho detto all'IA cosa dovrebbe fare il codice, non cosa fa
  • [ ] Mi sono concentrato sui percorsi di rischio effettivi, non sul numero di coperture
  • [] Ho utilizzato l'identificatore stabile nei test dell'interfaccia utente, non mi sono associato al testo