Menu

Coerenza dei campi di identità: perché i test passano su dati sbagliati

La coerenza dei campi di identità decide se un test dimostra qualcosa. Quando i campi non concordano, i dati finti fanno sembrare sano un sistema rotto e i guasti diventano irriproducibili.

Pubblicato

  • dati di test
  • identità
  • coerenza

La coerenza dei campi di identità è la proprietà che rende utilizzabile un insieme di valori generati. Ogni campo di un record può essere individualmente plausibile mentre il record nel suo insieme descrive qualcosa di impossibile — una via in un paese, un codice postale di un altro, un numero di telefono appartenente a un terzo — ed è esattamente lo stato in cui i test smettono di dire la verità.

Questo articolo spiega come nascono i record incoerenti, perché lasciano passare i test quando dovrebbero fallire, e cosa serve per mantenere coerente un dataset di test mentre cresce.

Perché campi individualmente corretti producono un record sbagliato?

La casualità è il colpevole abituale, ed è controintuitivo quanto rapidamente produca assurdità. Estrai un paese, poi estrai una città in modo indipendente, e la coppia discordarà con probabilità vicina a uno. Ciascun valore è estratto dal pool giusto; nulla è malformato; semplicemente la combinazione non si verifica mai.

I record costruiti a mano falliscono in modo diverso ma non meno spesso. Chi li scrive di solito procede campo per campo, verificando ogni valore contro la propria conoscenza, e non ha motivo di tenere a mente contemporaneamente il paese, la divisione, il codice postale e il prefisso telefonico. Il risultato è un record che sembra accurato ed è internamente contraddittorio.

C’è una terza fonte, più silenziosa di entrambe: i record assemblati da più fonti. Una riga di staging può prendere il nome da un seed, l’indirizzo da una fixture e i dati di contatto da qualunque cosa avesse aperta l’autore del test. Ogni parte andava bene da dove veniva.

Dove l’incoerenza si trasforma in un falso superamento

Considera una regola che dice che un cliente deve avere almeno una certa età per acquistare un prodotto, e un test che verifica che la regola funzioni. Con una data di nascita in un secolo e un’età memorizzata di un altro, il test può esercitare il ramo di accettazione mentre il record che sta testando avrebbe dovuto essere rifiutato — e nulla segnala un problema, perché nessun controllo è fallito.

Coppia incoerente Cosa nasconde
Paese e forma del codice postale Tutta la validazione del codice postale, perché il codice è comunque ben formato
Paese e prefisso telefonico La logica di locale e di instradamento, che in silenzio ricade su un valore predefinito
Data di nascita e soglia di età I cancelli di età, quindi un test superato dimostra solo che il percorso di accettazione gira
Indirizzo e formato dell’identificatore La validazione dell’identificatore, che viene saltata quando il paese è ambiguo
Divisione e intervallo del codice postale La normalizzazione dell’indirizzo, perché nessuna regola può essere applicata a una contraddizione

Lo schema in ogni riga è lo stesso: l’incoerenza rimuove l’input che avrebbe innescato il guasto. Una suite di test piena di tali record non è debole perché manca di asserzioni; è debole perché i suoi input non raggiungono mai i rami in cui vivono le asserzioni.

I dati incoerenti vanno rifiutati o riparati?

Dipende da chi li detiene, e sbagliare questo causa danni propri. I dati in arrivo da una persona dovrebbero essere riparati dove l’intento è inequivocabile e interrogati dove non lo è, perché c’è un essere umano che aspetta. I dati generati e delle fixture dovrebbero essere rifiutati senza appello, perché non c’è alcun intento da recuperare e un record riparato nasconde il difetto in qualunque cosa l’abbia prodotto.

La regola pratica per un generatore è che l’incoerenza è un bug nel generatore, non una proprietà da tollerare a valle. Qualunque altra cosa abitua il team a scrivere codice tollerante che in seguito incontrerà input reale e lo inghiottirà.

Per la validazione nel prodotto, la domanda utile è cosa dovrebbe fare un controllo di coerenza fallito al record. Un codice postale mancante è una lacuna di inserimento, e l’utente può correggerla. Un codice postale che esiste ma appartiene a una regione diversa è una contraddizione, e nessun tentativo ripetuto dell’utente la risolverà senza che cambi anche la regione. I due meritano un trattamento diverso.

Quanto deve essere forte una regola di coerenza?

Rendila il più debole possibile pur intercettando i guasti che contano, e sii esplicito su quale sia. Le regole hanno tre forze, e mescolarle senza etichette è il modo in cui un codebase finisce con una validazione che nessuno sa spiegare.

  • Un avviso registra la discordanza e lascia passare il record, il che è giusto per relazioni inferite anziché dichiarate.
  • Un rifiuto blocca il record, il che è giusto quando la discordanza è impossibile anziché solo insolita.
  • Una riparazione riscrive un valore per concordare con un altro, che è la più pericolosa delle tre e dovrebbe essere usata solo dove la precedenza è documentata.

La maggior parte della confusione in questo ambito nasce dal trattare una correlazione statistica come una regola ferrea. Un prefisso telefonico di solito implica un paese, ma non sempre; un codice postale di solito implica una regione, ma esistono zone di confine ed eccezioni. Codificare una tendenza come un divieto rifiuta persone reali, e lo fa più spesso proprio per gli utenti che assomigliano meno alle assunzioni nei dati.

I record generati devono essere coerenti in tutto il lotto?

Dentro un record, sì. Attraverso un lotto, no — e confondere le due cose spreca sforzi in una direzione e crea difetti nell’altra. Un lotto di mille record dovrebbe contenere varietà: regioni diverse, forme di nome diverse, fasce di età diverse, alcuni record con campi lasciati assenti. Non dovrebbe contenere mille record che ciascuno pretende di essere la stessa persona.

C’è una ragione pratica per mantenere i lotti internamente diversi. Un test che gira su cento record quasi identici esercita un solo percorso di codice cento volte e riporta successo. Lo stesso test su cento record vari esercita i rami che contano, ed è ciò che una prova di carico o di migrazione sta in realtà cercando di stabilire.

Dove un lotto ha bisogno di omogeneità è nella riproducibilità: lo stesso input dovrebbe produrre lo stesso lotto, così che un guasto trovato una volta possa essere trovato di nuovo. I record generati dal generatore di identità e dati di test mantengono quella proprietà derivando tutto da una chiave di identità, ed è ciò che consente a un lotto di essere vario e ripetibile allo stesso tempo. I valori restano record sintetici per i test software, non dettagli di persone reali.

Quali abbinamenti si rompono più spesso in pratica?

Quattro abbinamenti sono responsabili della maggior parte dei difetti. Il paese con il blocco indirizzo è il primo, perché le forme degli indirizzi sono la parte più evidentemente nazionale di un record. Il paese con il prefisso telefonico è il secondo, perché i prefissi sono brevi e facili da lasciare scollegati. La data di nascita con il cancello di età è il terzo, perché il cancello è di solito espresso come un numero anziché come un confronto. Il paese con il numero di identificazione è il quarto, perché un numero che è solo a forma di cifre supera un controllo debole ovunque.

Ognuno di questi ha un test economico: genera un record, modifica a mano un membro della coppia e conferma che il sistema se ne accorga. Se non se ne accorge, l’abbinamento non è mai stato realmente validato, e il record che avrebbe dovuto fallire stava passando per tutto il tempo.

Per gli sviluppatori: dove imporre le regole

Genera nell’ordine delle dipendenze e valida nello stesso ordine. Prima il paese, poi la divisione che gli appartiene, poi tutto ciò che deriva da quei due — indirizzo, codice postale, prefisso telefonico, formato dell’identificatore, valuta e locale. Un generatore che estrae i campi nell’ordine in cui il modulo li visualizza produrrà contraddizioni, perché l’ordine del modulo riguarda la presentazione e l’ordine dei dati riguarda la causalità.

Metti la validazione tra campi in un unico posto invece di sparpagliarla tra il modulo, l’API e il database. Le regole duplicate derivano, e la versione che deriva è sempre quella che nessuno sta leggendo. Modella esplicitamente ogni abbinamento, così che un revisore possa vedere quale valore vincola quale, e assegna a ogni regola un’etichetta di forza, così che un lettore successivo sappia se blocca o si limita ad avvisare.

Per le fixture, includi un record deliberatamente incoerente accanto a quelli validi — la stessa persona con esattamente un abbinamento rotto — e asserisci che il sistema lo rifiuti. Quel singolo caso è la fixture più preziosa dell’insieme, perché è l’unica che dimostra che le regole di coerenza sono ancora attive. Di nuovo, tutto questo è dato sintetico per i test: non è la descrizione di alcuna persona reale e non deve essere usato per sostituirne una.

Passi successivi

Scrivi i cinque abbinamenti di campi su cui si basa il tuo prodotto e controlla ciascuno nel codice; se un abbinamento non è imposto da nessuna parte, viene assunto anziché verificato. Poi estrai un lotto di record generati dal generatore di identità e falli passare attraverso un percorso di migrazione o di importazione, osservando le righe che riescono per la ragione sbagliata. L’articolo sulle fixture di test spiega come mantenere permanentemente nella suite un record rotto, così che questa proprietà non regredisca mai.

Continua a leggere

Guide su Generatore di identità e dati di test