Start free
Andrew Hanna

Andrew Hanna

Een Salesforce-sandbox seeden met realistische data

Een Salesforce-sandbox seeden met realistische data

Kort antwoord: een sandbox goed seeden is drie klussen, geen een. Trek een relatiebewuste doorsnede uit productie in plaats van een aantal records, laad die van ouder naar kind met stabiele external ID's zodat dezelfde set opnieuw geladen kan worden, en anonimiseer deterministisch zodat de data zich nog steeds als echte data gedraagt. Zet de seed-definitie daarna in versiebeheer naast je metadata, want wat seed-sets doodt is niet de eerste load, maar de schemawijziging drie sprints later.

Wat is sandbox seeding?

Sandbox seeding is het kopieren van een deelverzameling productierecords naar een lagere omgeving, zodat de org realistische data heeft om op te ontwikkelen en te testen, met gevoelige waarden gemaskeerd voordat ze landen. Het is een dataprobleem, geen metadataprobleem: een sandbox refresh brengt de configuratie mee en laat je in de meeste gevallen achter met een lege of onbruikbare org.

Welke sandboxen moeten echt geseed worden?

Alleen die geen data voor je kopieren. Volgens de Salesforce-documentatie over sandboxlicenties en opslaglimieten: Developer (200 MB) en Developer Pro (1 GB) kopieren alleen metadata en zijn dagelijks te verversen, dus die seed je. Partial Copy (5 GB, elke 5 dagen) brengt een sample via een sandboxtemplate en de gaten vul je zelf. Full (zo groot als productie, elke 29 dagen) brengt alles mee, en juist daarom telt maskeren daar zwaarder. Scratch orgs beginnen altijd leeg, dus daar is seeden verplicht.

Hoe kies je een relatiebewuste doorsnede?

De klassieke fout is selecteren op volume: pak 500 Accounts, pak 500 Contacts, hoop dat ze aan elkaar hangen. Dat doen ze niet, en testers bouwen vervolgens een week lang de records die ze beloofd kregen.

Selecteer in plaats daarvan op graaf, vanuit een kleine set rootrecords:

  1. Kies de roots bewust. Twintig tot vijftig Accounts die samen je record types, valuta, landen, territories en randgevallen dekken. Een enorme klant, een gloednieuwe, een met een kapot adres.
  2. Loop naar beneden door de kinderen. Contacts, Opportunities, regelitems, Cases, custom objects en de junction objects ertussen.
  3. Loop terug omhoog via de lookups. Wijst een Opportunity naar een Pricebook, een Campaign of een custom Contract, dan komen die ouders mee, anders faalt de insert.
  4. Behandel referentiedata apart. Producten, pricebook entries en configuratierecords zijn een volledige kopie van een kleine tabel, geen doorsnede van een graaf.

Een paar honderd goed verbonden records verslaan honderdduizend losse records voor elk doel behalve performancetesten.

In welke volgorde moeten de records geladen worden?

Strikte afhankelijkheidsvolgorde, ouders voor kinderen, en elk object gesleuteld op iets stabiels.

  • Neem nooit Salesforce-ID's mee tussen orgs. Die overleven het niet. Zet een tekstveld als external ID op elk geseed object, vul het vanuit het bronrecord en doe een upsert daarop. Nu is de load idempotent: draai hem twee keer en je werkt bij in plaats van dupliceert.
  • Doe circulaire referenties in twee passes. Self-lookups zoals Account.ParentId, en paren die naar elkaar wijzen, kun je niet in een insert oplossen. Laad de records met de lookup leeg en draai daarna een tweede pass die alleen de lookup zet.
  • Map het eigenaarschap. Owner en elke User-lookup lost niet op: sandbox-usernames krijgen een suffix en je productiegebruikers bestaan er misschien niet. Hermap ze voor de load.
  • Junctions als laatste. Laad een junction object pas als beide masters bestaan.
  • Omzeil automatisering, deactiveer haar niet. Triggers, flows, validatie- en duplicate rules vuren allemaal tijdens een seed-load. Een bypass-schakelaar die je automatisering controleert is beter dan deactivaties naar een org deployen.

Hoe anonimiseer je zonder de data waardeloos te maken?

Maskeren dat ruis oplevert is net zo slecht als niet maskeren, want niemand vertrouwt een test die op onzin faalde. Kies de techniek per veld:

  • Deterministische pseudoniemen voor alles dat gebruikt wordt in joins, matching of ontdubbeling. Dezelfde invoer moet altijd dezelfde uitvoer geven, zodat een klant over alle objecten heen een klant blijft.
  • Shufflen binnen de kolom waar de verdeling belangrijker is dan de waarde, zoals omzetbanden of sluitdatums waarop je rapporteert.
  • Volledig wissen voor velden die geen enkele test aanraakt. Vrije notities, omschrijvingsvelden en bijlagen zijn waar PII zich echt verstopt.
  • Neutraliseer alles wat kan uitgaan. E-mailadressen, telefoonnummers en external ids die integraties gebruiken, herschrijf je naar waarden die geen echt persoon kunnen bereiken, en controleer de e-mailinstelling van de sandbox voor de eerste load.

Salesforce levert Anonymize for Salesforce, en Gearset, Odaseva en Flosum verkopen seeding-tooling met maskeren erin. Wat je ook gebruikt: de maskeerregels moeten een keer schriftelijk worden goedgekeurd door wie verantwoordelijk is voor gegevensbescherming.

Wat gebeurt er als het schema verandert?

Dit stuk behandelt bijna niemand, en het is precies waarom de meeste seed-sets binnen een kwartaal dood zijn. Een seed-definitie is een vaste foto van je schema: veldlijsten, picklistwaarden, verplichte velden, validatieregels. Zet een nieuw verplicht veld live en elke load daarna faalt.

Behandel de seed-set als broncode, niet als een opgeslagen configuratie in iemands tool:

  • Zet de seed-definitie in de repo, naast de metadata waarvan hij afhangt, zodat een schemawijziging en de bijbehorende seed-wijziging in dezelfde pull request landen.
  • Leid kolommen af uit een describe-aanroep in plaats van een handmatige veldlijst vast te pinnen, zodat nieuwe velden niet stilletjes wegvallen.
  • Draai de load in CI tegen een scratch org bij elke pull request die objecten, velden of validatieregels raakt. Een mislukte seed-load is een terechte build failure: hij betekent dat je net iets hebt uitgerold dat het aanmaken van data breekt.
  • Leid de set opnieuw af na elke refresh. Picklistwaarden worden hernoemd en record types verdwijnen; een seed-set die in maart klopte is in juni een rij validatiefouten.

In Serpent is een data-operatie een volwaardige pipeline-actie in plaats van handwerk, waardoor de seed-run in dezelfde pipeline past als de deployment die hij ondersteunt.

Koppel het ritme tot slot aan je releases: elke iteratie voor ontwikkelsandboxen, elke testronde voor UAT, altijd na een refresh. Omdat de load idempotent is en in versiebeheer staat, is dat een pipeline-run in plaats van een project. Meer Salesforce DevOps-gidsen.

FAQ

Hoeveel data moet een geseede sandbox bevatten?

Genoeg om elk record type, pad en randgeval te dekken, meestal een paar honderd verbonden records. Volume telt alleen bij load tests.

Kan ik niet gewoon Data Loader gebruiken?

Voor een kleine set wel. Laadvolgorde, ID-hermapping en maskeren doe je dan zelf, en je herhaalt alle drie met de hand na elke refresh.

Blijft mijn geseede data staan na een sandbox refresh?

Nee. Een refresh vervangt de sandbox, dus alles wat je geseed had is weg. Plan de seed als vaste stap na elke refresh.

Gerelateerde artikelen

Benieuwd naar sneller releasen voordat je instapt? Laten we praten

Vrijblijvend.