Menu

Consistentie van identiteitsvelden: waarom tests slagen op slechte gegevens

Consistentie van identiteitsvelden bepaalt of een test iets bewijst. Wanneer velden elkaar tegenspreken, laat nepdata een kapot systeem gezond lijken en worden fouten niet reproduceerbaar.

Gepubliceerd

  • testgegevens
  • identiteit
  • consistentie

Consistentie van identiteitsvelden is de eigenschap die een set gegenereerde waarden überhaupt bruikbaar maakt. Elk veld in een record kan afzonderlijk plausibel zijn terwijl het record als geheel iets onmogelijks beschrijft — een straat in het ene land, een postcode uit een ander, een telefoonnummer dat bij een derde hoort — en dat is precies de toestand waarin testen ophoudt de waarheid te vertellen.

Dit artikel legt uit hoe inconsistente records ontstaan, waarom ze tests laten slagen terwijl ze zouden moeten falen, en wat er nodig is om een testdataset coherent te houden terwijl die groeit.

Waarom maken afzonderlijk correcte velden een verkeerd record?

Willekeurigheid is de gebruikelijke boosdoener, en het is contra-intuïtief hoe snel die onzin produceert. Trek een land, trek dan onafhankelijk een stad, en het paar zal met waarschijnlijkheid bijna één niet overeenstemmen. De waarden zijn elk uit de juiste poel getrokken; niets is misvormd; de combinatie komt simpelweg nooit voor.

Met de hand gebouwde records falen anders maar niet minder vaak. Wie ze schrijft, werkt doorgaans veld voor veld, controleert elke waarde tegen zijn eigen kennis, en heeft geen reden om het land, de regio, de postcode en het netnummer tegelijk in gedachten te houden. Het resultaat is een record dat zorgvuldig uitziet en intern tegenstrijdig is.

Er is een derde bron, stiller dan beide: records die uit meerdere bronnen zijn samengesteld. Een stagingrij kan zijn naam uit het ene zaadje halen, zijn adres uit een fixture, en zijn contactgegevens uit wat de testauteur toevallig open had. Elk deel was prima waar het vandaan kwam.

Waar inconsistentie verandert in een valse slaag

Stel een regel die zegt dat een klant een bepaalde minimumleeftijd moet hebben om een product te kopen, en een test die controleert dat de regel werkt. Met een geboortedatum in de ene eeuw en een opgeslagen leeftijd uit een andere, beproeft de test mogelijk de acceptatietak terwijl het record dat hij test afgewezen had moeten worden — en niets meldt een probleem, want geen enkele controle faalde.

Inconsistent paar Wat het verbergt
Land en vorm van postcode Alle postcodevalidatie, omdat de code nog goed gevormd is
Land en telefonische netnummer Locale- en routeringslogica, die stilletjes terugvalt op een standaard
Geboortedatum en leeftijdsdrempel Leeftijdspoorten, zodat een geslaagde test alleen bewijst dat het acceptatiepad loopt
Adres en identificatieformaat Identificatievalidatie, die wordt overgeslagen wanneer het land dubbelzinnig is
Regio en postcodebereik Adresnormalisatie, omdat geen regel op een tegenstrijdigheid kan worden toegepast

Het patroon in elke rij is hetzelfde: de inconsistentie haalt de invoer weg die de fout zou hebben veroorzaakt. Een testsuite vol zulke records is niet zwak omdat ze asserties mist; ze is zwak omdat haar invoer nooit de takken bereikt waar de asserties leven.

Moeten inconsistente gegevens worden afgewezen of hersteld?

Het hangt ervan af wie ze vasthoudt, en dit verkeerd doen richt zijn eigen schade aan. Inkomende gegevens van een persoon moeten worden hersteld waar de bedoeling ondubbelzinnig is en bevraagd waar dat niet zo is, omdat er een mens wacht. Gegenereerde en fixture-gegevens moeten ronduit worden afgewezen, omdat er geen bedoeling te herstellen valt en een hersteld record het defect verbergt in wat het ook heeft geproduceerd.

De vuistregel voor een generator is dat inconsistentie een bug in de generator is in plaats van een eigenschap die stroomafwaarts moet worden getolereerd. Alles anders leert het team tolerante code te schrijven die later echte invoer tegenkomt en die inslikt.

Voor validatie in het product is de nuttige vraag wat een mislukte consistentiecontrole met het record moet doen. Een ontbrekende postcode is een gat in de invoer, en de gebruiker kan het oplossen. Een postcode die bestaat maar bij een andere regio hoort, is een tegenstrijdigheid, en geen enkele herhaling door de gebruiker lost die op zonder dat de regio ook verandert. Die twee verdienen een verschillende behandeling.

Hoe sterk moet een consistentieregel zijn?

Maak hem zo zwak als hij kan zijn terwijl hij nog steeds de fouten opvangt die ertoe doen, en wees expliciet over welke het is. Regels komen in drie sterktes, en ze zonder labels mengen is hoe een codebase validatie krijgt die niemand kan uitleggen.

  • Een waarschuwing legt de onenigheid vast en laat het record door, wat juist is voor afgeleide in plaats van vermelde relaties.
  • Een afwijzing blokkeert het record, wat juist is wanneer de onenigheid onmogelijk is in plaats van slechts ongewoon.
  • Een herstel herschrijft de ene waarde zodat die met een andere overeenstemt, de gevaarlijkste van de drie, en mag alleen worden gebruikt waar de voorrang is gedocumenteerd.

De meeste verwarring op dit gebied komt van het behandelen van een statistische correlatie als een harde regel. Een netnummer impliceert meestal een land, maar niet altijd; een postcode impliceert meestal een regio, maar grensgebieden en uitzonderingen bestaan. Een neiging coderen als een verbod wijst echte mensen af, en dat doet het vaakst voor de gebruikers die het minst op de aannames in de gegevens lijken.

Moeten gegenereerde records consistent zijn over de hele batch?

Binnen een record wel. Over een batch niet — en die twee verwarren verspilt inspanning in de ene richting en veroorzaakt defecten in de andere. Een batch van duizend records moet variatie bevatten: verschillende regio’s, verschillende naamvormen, verschillende leeftijdsgroepen, sommige records met velden die afwezig zijn gelaten. Hij mag geen duizend records bevatten die elk beweren dezelfde persoon te zijn.

Er is een praktische reden om batches intern divers te houden. Een test die tegen honderd bijna identieke records loopt, beproeft honderd keer hetzelfde codepad en meldt succes. Dezelfde test tegen honderd gevarieerde records beproeft de takken die ertoe doen, wat een load- of migratierepetitie feitelijk probeert vast te stellen.

Waar een batch wel homogeniteit nodig heeft, is reproduceerbaarheid: dezelfde invoer moet dezelfde batch opleveren, zodat een fout die één keer is gevonden opnieuw kan worden gevonden. Gegenereerde records van de generator voor identiteits- en testgegevens behouden die eigenschap door alles af te leiden van een identiteitssleutel, wat een batch tegelijk gevarieerd en herhaalbaar maakt. De waarden blijven synthetische records voor softwaretesten, niet de gegevens van echte mensen.

Welke paren breken in de praktijk het vaakst?

Vier paren zijn verantwoordelijk voor de meerderheid van de defecten. Het land met het adresblok is de eerste, omdat adresvormen het meest duidelijk nationale deel van een record zijn. Het land met het netnummer is de tweede, omdat netnummers kort zijn en makkelijk ongekoppeld blijven. De geboortedatum met de leeftijdspoort is de derde, omdat de poort meestal als een getal wordt uitgedrukt in plaats van als een vergelijking. Het land met het identificatienummer is de vierde, omdat een nummer dat slechts cijfervormig is overal een zwakke controle doorstaat.

Elk van deze heeft een goedkope test: genereer een record, wijzig met de hand één lid van het paar, en bevestig dat het systeem het opmerkt. Als dat niet gebeurt, is het paar nooit daadwerkelijk gevalideerd, en slaagde het record dat had moeten falen al die tijd.

Voor ontwikkelaars: waar de regels moeten worden gehandhaafd

Genereer in afhankelijkheidsvolgorde en valideer in dezelfde volgorde. Eerst het land, dan de regio die erbij hoort, dan alles wat van die twee is afgeleid — adres, postcode, netnummer, identificatieformaat, valuta en locale. Een generator die velden trekt in de volgorde waarin het formulier ze toont, produceert tegenstrijdigheden, want de volgorde van het formulier gaat over presentatie en de volgorde van de gegevens gaat over causaliteit.

Zet validatie over velden heen op één plek in plaats van die te verstrooien over het formulier, de API en de database. Gedupliceerde regels gaan afwijken, en de versie die afwijkt is altijd degene die niemand leest. Modelleer elk paar expliciet zodat een reviewer kan zien welke waarde welke beperkt, en geef elke regel een sterkte-label zodat een latere lezer weet of die blokkeert of slechts waarschuwt.

Neem voor fixtures een bewust inconsistent record op naast de geldige — dezelfde persoon met precies één paar gebroken — en assert dat het systeem het afwijst. Dat ene geval is de meest waardevolle fixture in de set, want het is de enige die bewijst dat de consistentieregels nog aanstaan. Nogmaals, dit alles is synthetische data voor het testen: het is geen beschrijving van een echt persoon, en het mag niet worden gebruikt om er een te vertegenwoordigen.

Volgende stappen

Schrijf de vijf veldparen op waarop uw product vertrouwt en controleer elk ervan in de code; als een paar nergens wordt gehandhaafd, wordt het aangenomen in plaats van geverifieerd. Haal dan een batch gegenereerde records uit de identiteitsgenerator en voer ze door een migratie- of importpad, en let op rijen die om de verkeerde reden slagen. Het artikel over testfixtures legt uit hoe u één kapot record permanent in de suite houdt zodat deze eigenschap nooit achteruitgaat.

Verder lezen

Handleidingen over Identiteits- en testdatagenerator