I dati di test sintetici sono dati prodotti artificialmente anziché raccolti. Non descrivono nessuno, possono essere rigenerati su richiesta e non devono mai essere mascherati, cancellati o oggetto di richieste legali. Per i team che testano form di indirizzo, flussi di checkout o pipeline di importazione, sono l'unico tipo di dati utilizzabile liberamente in CI, negli screenshot e nelle demo.
Il problema è che i dati sintetici sono utili solo quando sono sia plausibili sia sicuri. I dati implausibili non intercettano i bug. I dati non sicuri li creano. Questa guida illustra la via di mezzo: generazione con seed per la riproducibilità, intervalli di valori riservati che non possono collidere con la realtà, integrità referenziale tra le entità e gli identificatori specifici che un generatore dovrebbe rifiutarsi di produrre.
Cosa conta davvero come dato sintetico
I dati sintetici sono generati da regole, non campionati da persone. Un nome composto da una lista di nomi, un indirizzo composto da un fixture di paese, un numero di telefono da un blocco riservato, un'email su un dominio riservato: ognuno è prodotto artificialmente e nessuno si riferisce a un soggetto reale. La riproducibilità è ciò che li distingue dal rumore casuale, perché un output senza seed non può essere revisionato, confrontato con un diff o riprodotto.
I dati di produzione anonimizzati non sono sintetici. Mascherare una riga reale lascia la stessa distribuzione e spesso lo stesso rischio di re-identificazione, e una colonna EMAIL mascherata che mantiene il dominio rivela comunque il datore di lavoro. Se un test ha bisogno di dati con la forma della produzione, è una questione separata di aggregazione e accesso, non qualcosa che un generatore possa onestamente fornire.
- Generati da regole, non campionati da persone
- Riproducibili da un seed
- Revisionabili: un diff ti dice cosa è cambiato
- Mai derivati da una riga di produzione
Generazione con seed versus file fixture versionati
Un file fixture versionato ha un vantaggio: è facile da ispezionare. Ha diversi problemi. Va alla deriva, perché nessuno lo aggiorna quando lo schema cambia. Appesantisce il repository. Viene copiato tra progetti finché nessuno sa più quale versione sia quella corrente. E diventa silenziosamente l'unico dato su cui chiunque testa, così la suite copre esattamente i valori che qualcuno ha digitato nel 2021.
La generazione con seed mantiene l'input minuscolo e l'output grande. Il seed più la versione del generatore sono il fixture. Rigenera su richiesta, salva solo il primo e l'ultimo record per la revisione e tratta qualsiasi cambiamento nell'output del generatore come una modifica deliberata che richiede un nuovo baseline. L'unico requisito è che il generatore sia bloccato a una versione precisa, perché un generatore aggiornato con un algoritmo modificato è un nuovo set di dati anche con lo stesso seed.
| Approccio | Costo nel repo | Riproducibile | Rischio di deriva |
|---|---|---|---|
| Fixture JSON versionati | Alto | Sì, ma congelati | Cresce con l'età |
| Generatore con seed al momento del test | Basso | Sì, con una versione bloccata | Basso |
| Dati casuali senza seed | Basso | No | Alto, e instabile |
| Dump di produzione mascherato | Alto | No | Alto, più rischio per la privacy |
Intervalli riservati che non possono collidere con la realtà
Diversi standard riservano valori per documentazione e test. Usarli non è una preferenza di stile; è la differenza tra un fixture garantito innocuo e uno che potrebbe appartenere a qualcuno. I blocchi riservati sono stabili, ampiamente documentati e accettati dalla maggior parte dei validatori come sintatticamente normali.
Per l'email, usa un dominio sotto .test, come example.test, che è riservato e non può essere registrato. Per i numeri di telefono nel Piano di Numerazione Nordamericano, il blocco da 555-0100 a 555-0199 è riservato all'uso fittizio. Per gli indirizzi IP, gli intervalli di documentazione sono 192.0.2.0/24, 198.51.100.0/24 e 203.0.113.0/24 in IPv4 e 2001:db8::/32 in IPv6. Per gli indirizzi MAC, l'intervallo di documentazione va da 00-00-5E-00-53-00 a 00-00-5E-00-53-FF, e anche gli indirizzi amministrati localmente con il bit U/L impostato sono sicuri per i fixture.
| Tipo di valore | Riservato per i test | Autorità |
|---|---|---|
| Dominio email | example.test, example.com, example.org | RFC 2606 e RFC 6761 |
| Dominio web | .test, .invalid, .localhost | RFC 2606 |
| Telefono USA e Canada | NANP 555-0100 a 555-0199 | Intervallo fittizio NANP |
| Documentazione IPv4 | 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 | RFC 5737 |
| Documentazione IPv6 | 2001:db8::/32 | RFC 3849 |
| Documentazione MAC | 00-00-5E-00-53-xx | RFC 7042 |
| MAC amministrato localmente | Primo ottetto 0x02, bit I/G a zero | Bit U/L IEEE 802 |
Integrità referenziale tra entità generate
La maggior parte dei sistemi ha bisogno di più di un'entità. Un ordine ha un cliente, un indirizzo di spedizione e un indirizzo di fatturazione, e i tre devono essere coerenti nei modi imposti dallo schema. Se l'indirizzo di fatturazione è negli Stati Uniti e quello di spedizione in Giappone, il calcolo delle imposte e la selezione del corriere devono accettare quella combinazione, altrimenti il test fallisce per un motivo non correlato al comportamento in esame.
Genera relazioni, non righe. Deriva i seed figli dal seed padre, così l'ordine e i suoi indirizzi sono riproducibili come unità. Decidi deliberatamente quali campi devono essere coerenti: il paese tra spedizione e fatturazione di solito è lo stesso, il codice postale deve corrispondere alla città nel fixture, la valuta deve corrispondere al paese. Codifica quei vincoli nella factory, così un fixture rotto fallisce al momento della generazione anziché in un'asserzione tre livelli più in basso.
- Deriva i seed figli dal seed padre, non dall'orologio
- Mantieni il paese coerente tra fatturazione, spedizione e imposte
- Mantieni il codice postale coerente con il fixture della città
- Mantieni la valuta coerente con il paese
- Fai fallire al momento della generazione quando un vincolo viene violato
Cosa questo sito si rifiuta di generare
Il sito non genera numeri di previdenza sociale, numeri di carte di pagamento, valori IMEI o IMSI, indirizzi di dispositivi Bluetooth o numeri di serie. Ogni rifiuto ha una ragione. I SSN sono identificatori legalmente limitati negli Stati Uniti. I numeri di carta hanno un checksum Luhn, quindi uno plausibile può superare un validatore ingenuo e poi essere incollato in un ticket di assistenza. Gli IMEI hanno una cifra di controllo e un registro di allocazione. Gli indirizzi Bluetooth condividono il formato MAC ma non hanno alcun significato di produttore, e uno generato invita esattamente alla confusione che gli strumenti MAC sono progettati per evitare.
Lo stesso ragionamento vale per qualsiasi identificatore con un checksum o un registro. Se un test ne ha davvero bisogno, usa i valori di test pubblicati ufficialmente dal processore o dall'autorità emittente, non un generatore. Così il valore resta ovviamente falso per chiunque riconosca il pattern di test, e il tuo screenshot resta fuori da una revisione di conformità.
| Identificatore | Generato qui | Alternativa corretta |
|---|---|---|
| Numero di previdenza sociale | No | Non usare mai un SSN reale o realistico |
| Numero di carta di pagamento | No | Carte di test del processore per la sandbox |
| IMEI o IMSI | No | Valori di test del fornitore, se esistono |
| Indirizzo Bluetooth | No | Non necessario per i test dei form di indirizzo |
| Numero di serie del dispositivo | No | Un id fixture opaco che controlli tu |
| Indirizzo email | Sì, solo example.test | Dominio sicuro e non risolvibile |
| Numero di telefono | Sì, NANP 555-0100 a 555-0199 | Intervallo fittizio riservato |
Volume, determinismo e prestazioni
Generare cento record al momento del test è economico. Generarne dieci milioni no, e farlo dentro il setup di un test dominerà il tempo di esecuzione. Precalcola grandi volumi una volta in uno store isolato, con il seed registrato nel manifest, e tieni il generatore fuori dal percorso critico. Per volumi medi, genera in un unico batch anziché riga per riga, perché il setup per riga è di solito il costo reale.
Anche il determinismo ha una dimensione prestazionale. I worker paralleli non devono condividere un unico generatore sequenziale, perché l'interleaving cambia quale worker riceve quale record. Assegna a ogni worker il proprio seed derivato dal seed dell'esecuzione e dall'indice del worker, così il dataset è stabile indipendentemente dallo scheduling. Questo rende anche riproducibile un fallimento sul worker tre senza rieseguire l'intera suite.
- Volumi piccoli: genera inline, con seed
- Volumi grandi: precalcola in uno store isolato con un manifest
- Worker paralleli: deriva un seed per indice del worker
- Non condividere mai una singola istanza del generatore tra thread
- Registra la versione del generatore insieme al seed
Tenere i dati sintetici fuori dalle pipeline reali
Il pericolo dei buoni dati sintetici è che sembrano reali. Metti un marcatore su ogni record generato: un flag fixture, un tenant dedicato, un'email su example.test, un telefono nell'intervallo 555-01xx. Blocca quei record dall'invio di email, dall'acquisizione di pagamenti o dall'ingresso in analytics. Un cliente demo che raggiunge un CRM di produzione è un incidente di assistenza in attesa che un venditore se ne accorga.
Tieni anche i dati generati fuori dai log conservati per conformità e dagli screenshot che verranno pubblicati. Anche se i valori non descrivono nessuno, un lettore non può capirlo dall'immagine, e spiegarlo dopo costa più che etichettarlo ora. Se uno screenshot deve mostrare un indirizzo realistico, usa un valore dell'intervallo di documentazione e aggiungi una didascalia visibile "dati di esempio".
- Etichetta ogni riga generata con un flag fixture o un tenant
- Blocca i tenant fixture da email, pagamenti e analytics
- Usa example.test e 555-01xx, mai un dominio reale plausibile
- Aggiungi didascalie agli screenshot che mostrano valori generati
- Elimina i fixture dallo staging condiviso secondo una pianificazione
Una checklist di revisione prima dell'uso
Prima che un dataset generato venga usato in un ambiente condiviso, quattro domande richiedono risposta. Da dove viene, e può essere rigenerato? Ogni valore è in un intervallo riservato o amministrato localmente? Soddisfa i vincoli dello schema e le regole referenziali? Ed è etichettato in modo che un lettore umano non possa scambiarlo per un cliente?
Se una qualsiasi risposta è no, il dataset non è pronto. È volutamente rigoroso, perché il costo di una risposta sbagliata è asimmetrico: rigenerare richiede minuti, mentre un cliente sintetico in un report sui ricavi può distorcere le decisioni per un trimestre. Esegui la checklist come parte della revisione, non come commento in un wiki.
| Domanda | Condizione di superamento | Prova |
|---|---|---|
| Origine | Seed e versione del generatore registrati | File manifest |
| Sicurezza | Tutti i valori in intervalli riservati o locali | Validatore eseguito sul dataset |
| Integrità | Schema e regole tra entità soddisfatti | Test della factory verdi |
| Etichettatura | Flag fixture su ogni riga | La query restituisce zero righe non etichettate |
Domande
- Sì, quando ogni valore è sintetico e riservato, ad esempio email example.test e telefoni NANP 555-01xx. Preferisci rigenerare da un seed anziché versionare grandi dataset.
- Quegli identificatori sono regolamentati o dotati di checksum, e un falso realistico può superare una validazione ingenua e finire in uno screenshot o in un ticket. Usa invece i valori di test ufficiali del processore o dell'autorità.
- Deriva un seed per worker dal seed dell'esecuzione e dall'indice del worker. Un unico generatore condiviso produce una sequenza diversa a seconda dello scheduling.
- No. Il mascheramento mantiene la distribuzione originale e spesso il rischio di re-identificazione. I dati sintetici sono generati da regole e non descrivono alcun soggetto reale.
- 38 paesi con cinque fixture di città ciascuno. Hong Kong e gli Emirati Arabi Uniti non restituiscono codice postale, perché nessuno dei due ne ha uno.
I dati di test sintetici sono sicuri da versionare?+
Perché il generatore si rifiuta di produrre valori di carte o SSN?+
Come mantengo riproducibili i test paralleli?+
I dati di produzione mascherati sono la stessa cosa?+
Quanti paesi coprono i dati di indirizzo sintetici?+
Gli esempi sono sintetici. Non usare un indirizzo generato per verifiche di identità, registrazione di account o consegne.