Menu

Test OTP nelle suite end-to-end: leggere il codice

Il test OTP significa estrarre il codice monouso da una casella di test e reinserirlo nel modulo. Qui si trattano parsing, freschezza, ripetizioni e il fallback umano.

Pubblicato

  • test end-to-end
  • codici monouso
  • automazione

Il test OTP è la parte piccola e ostinata di una suite end-to-end che legge un codice monouso da una casella e lo digita di nuovo in un modulo. Sembra banale finché non diventa inaffidabile, e lo diventa per ragioni che non hanno nulla a che fare con un codice sbagliato: un messaggio lento, un messaggio più vecchio ancora presente nella casella, un nuovo invio che è stato limitato. Questo articolo copre come rendere quel passo affidabile e quando smettere di automatizzarlo.

Di cosa ha bisogno una suite end-to-end da un messaggio con codice

Un messaggio con codice ha un solo compito: portare un segreto breve dalla tua applicazione a un posto dove il test possa leggerlo. Tutto il resto — impaginazione, grafica, piè di pagina, lingua — è decorazione dal punto di vista della suite.

È questa asimmetria a rendere il passo così facile da sbagliare. Poiché il test ha bisogno solo di una manciata di caratteri, è tentante estrarli alla leggera, dal primo messaggio che sembra abbastanza vicino. Il risultato è un test che di solito passa e occasionalmente legge il messaggio sbagliato, che è il tipo più costoso di instabilità: è abbastanza raro da essere liquidato e abbastanza reale da nascondere un bug genuino.

Qual è il messaggio giusto?

L’identità, non solo la recentezza. La regola più sicura è una combinazione: il messaggio deve essere indirizzato all’indirizzo creato da questo caso, e deve essere il più recente dei messaggi corrispondenti in quella casella.

Entrambe le metà si guadagnano il loro posto. La corrispondenza sul destinatario rimuove la contaminazione tra test, perché un messaggio inviato all’indirizzo di un altro caso non può soddisfare l’asserzione per quanto sia nuovo. Preferire il più recente tra le corrispondenze gestisce il caso in cui lo stesso flusso è stato innescato due volte, una per un tentativo o per un’istanza precedente.

La corrispondenza sull’oggetto è un utile passo di restringimento quando una casella contiene legittimamente più di un tipo di posta — un messaggio di benvenuto e un codice, per esempio. Fai corrispondere una parte stabile dell’oggetto anziché l’intera riga, perché le parti decorative cambiano: lo stesso oggetto con un saluto diverso dovrebbe comunque corrispondere.

Perché i test che leggono codici diventano instabili?

Quattro cause spiegano la maggior parte del fenomeno, e ciascuna ha una soluzione diversa.

  • Un’attesa fissa. Dormire per un numero costante di secondi è una supposizione, e le supposizioni sono o troppo brevi quando il messaggio è lento o sprecamente lunghe quando è veloce. Esegui il polling finché il messaggio compare, con un tetto che faccia fallire il test anziché bloccare l’esecuzione.
  • Un messaggio vecchio. Se un caso riusa un indirizzo, o se un tentativo precedente ha lasciato un messaggio, una nuova ricerca può soddisfarsi con contenuto vecchio. Dai a ogni caso il proprio indirizzo o, come minimo, registra cosa c’era prima che il flusso iniziasse e ignora tutto ciò che è più vecchio.
  • Un limite di reinvio. I flussi con codice di norma consentono solo pochi reinvii in una breve finestra, il che è una protezione deliberata anziché un difetto. Un test che ritenta chiedendo un altro codice finirà per essere rifiutato e fallirà per la ragione sbagliata; ritenta rileggendo la casella invece di premere il pulsante.
  • Un parsing troppo avido. Un corpo può contenere legittimamente diversi numeri — un riferimento, un timestamp, un prezzo — e un parser che prende la prima sequenza di cifre a volte prende quella sbagliata. Ancora l’estrazione al testo attorno al codice anziché alle sole cifre.

Quando deve restare un umano nel ciclo?

Alcuni passi non dovrebbero essere automatizzati, e fingere il contrario produce test di cui nessuno si fida.

Un umano è lo strumento giusto quando il flusso richiede un dispositivo che una pipeline non ha, quando il codice arriva attraverso un canale che non può essere letto a livello di programma, o quando l’asserzione è in realtà un giudizio su se il messaggio si legge bene. C’è anche un caso più semplice: alcuni fornitori scoraggiano attivamente la registrazione automatizzata, e una suite che aggira ciò non sta testando il prodotto, sta testando l’aggiramento.

Lo schema utile è un cancello manuale esplicito che fallisce in modo rumoroso invece di passare in silenzio. Un passo che dice che una persona deve controllare questo prima che l’esecuzione prosegua è onesto; un passo che prova e occasionalmente riesce non lo è.

Una casella sacrificabile per ogni esecuzione

La fixture più pulita per questo lavoro è una casella creata per il caso che ne ha bisogno e scartata dopo. Poiché non vi è mai stato inviato nient’altro, il messaggio più recente è quasi certamente quello giusto, e il problema della freschezza in gran parte svanisce.

La pagina della posta temporanea crea un indirizzo su richiesta: scegli un dominio di posta, gli dai facoltativamente un prefisso e compare una casella che elenca ciò che arriva. I codici sono mostrati separatamente, così possono essere copiati senza leggere l’intero corpo, il che è comodo quando è una persona a leggere ed è utile da imitare quando lo fa un software.

Questi indirizzi sono impalcature per un’esecuzione di test. Non rappresentano nessuno, vengono scartati con l’esecuzione e non devono mai essere registrati come identità reale o usati come punto di contatto di qualcuno.

Per gli sviluppatori: parsing, freschezza e tetti dei tentativi

Cinque decisioni fanno la differenza tra una suite che legge i codici e una suite di cui ci si fida in merito.

Dai a ogni caso il proprio indirizzo e fai in modo che l’indirizzo porti l’identità del caso, così che un messaggio possa essere attribuito per ispezione anziché per tempismo.

Esegui il polling con un tetto, e rendi il tetto parte del messaggio di fallimento. Quando scatta, il report dovrebbe dire quale indirizzo è stato letto, quanti messaggi conteneva e quali oggetti avevano. Senza questo, la persona successiva riesegue la pipeline invece di diagnosticarla.

Esegui il parsing in modo difensivo. Prendi la corrispondenza più recente sul destinatario e sull’oggetto atteso, poi estrai il codice dal contesto attorno ad esso. Se non viene trovato alcun codice, fallisci con il corpo anziché con un timeout generico.

Non disattivare mai un limite di frequenza per far passare un test. Il limite fa parte del comportamento sotto test, e una suite che lo spegne non descrive più il prodotto che i tuoi utenti incontrano. Gestisci invece il limite: scegli un indirizzo che non è stato usato di recente e leggi il messaggio esistente anziché richiederne uno nuovo.

Mantieni vivo il percorso umano. Per i casi in cui l’automazione non riesce davvero a leggere il codice, documenta il passo manuale e rendilo visibile nell’output dell’esecuzione, così che un controllo saltato non venga mai scambiato per uno superato.

L’articolo sul test dei flussi di verifica copre il flusso attorno al codice, e come funziona la posta temporanea spiega perché un messaggio lento o duplicato è normale anziché rotto.

Prossimi passi

Trova il passo del codice nella tua suite e controlla le due cose che mancano più spesso: se l’indirizzo è unico per il caso e se il messaggio di fallimento permetterebbe a qualcun altro di diagnosticare l’esecuzione senza ripeterla. Poi esegui lo stesso caso con un indirizzo creato nuovo dalla pagina della posta temporanea e vedi se l’instabilità che hai tollerato finora scompare.

Continua a leggere

Guide su Email temporanea (usa e getta / 10 minuti)