Start free
Andrew Hanna

Andrew Hanna

Comment alimenter une sandbox Salesforce avec des donnees realistes

Comment alimenter une sandbox Salesforce avec des donnees realistes

Reponse courte : bien alimenter une sandbox Salesforce, ce sont trois travaux, pas un. Extrayez une tranche de production consciente des relations plutot qu'un nombre d'enregistrements, chargez-la des parents vers les enfants avec des identifiants externes stables pour que le meme jeu puisse etre recharge, et anonymisez de facon deterministe pour que les donnees se comportent encore comme de vraies donnees. Versionnez ensuite la definition du jeu a cote de vos metadonnees, car ce qui tue un jeu de donnees n'est pas le premier chargement, c'est le changement de schema trois sprints plus tard.

Qu'est-ce que le seeding de sandbox ?

Le seeding consiste a copier un sous-ensemble d'enregistrements de production vers un environnement inferieur, afin que l'org dispose de donnees realistes pour developper et tester, les valeurs sensibles etant masquees avant leur arrivee. C'est un probleme de donnees, pas de metadonnees : un refresh de sandbox apporte la configuration et vous laisse, le plus souvent, une org vide ou inexploitable.

Quelles sandboxes ont vraiment besoin d'etre alimentees ?

Celles qui ne copient pas les donnees pour vous. D'apres la documentation Salesforce sur les licences et limites de stockage : Developer (200 Mo) et Developer Pro (1 Go) ne copient que les metadonnees et se rafraichissent chaque jour, ce sont celles que vous alimentez. Partial Copy (5 Go, tous les 5 jours) apporte un echantillon choisi par un modele et vous comblez les trous. Full (taille production, tous les 29 jours) apporte tout, et c'est pour cela que le masquage y compte davantage. Les scratch orgs demarrent toujours vides : le seeding y est obligatoire.

Comment choisir une tranche consciente des relations ?

L'echec classique consiste a selectionner par volume : 500 Accounts, 500 Contacts, en esperant qu'ils soient relies. Ils ne le sont pas, et les testeurs recreent toute la semaine les enregistrements promis.

Selectionnez plutot par graphe, en partant d'un petit ensemble d'enregistrements racines :

  1. Choisissez les racines avec intention. Vingt a cinquante Accounts couvrant ensemble vos record types, devises, pays, territoires et cas limites. Un tres gros client, un tout nouveau, un avec une adresse cassee.
  2. Descendez vers les enfants. Contacts, Opportunities, lignes, Cases, objets personnalises et les objets de jonction entre eux.
  3. Remontez par les lookups. Si une Opportunity pointe vers un Pricebook, une Campaign ou un Contract personnalise, ces parents suivent, sinon l'insertion echoue.
  4. Traitez les donnees de reference a part. Produits, entrees de pricebook et enregistrements de configuration sont la copie complete d'une petite table, pas une tranche de graphe.

Quelques centaines d'enregistrements bien relies valent mieux que cent mille enregistrements isoles, sauf pour les tests de charge.

Dans quel ordre charger les enregistrements ?

Ordre de dependance strict, les parents avant les enfants, et chaque objet cle sur quelque chose de stable.

  • Ne transportez jamais les identifiants Salesforce d'une org a l'autre. Ils ne survivent pas. Ajoutez un champ texte identifiant externe sur chaque objet alimente, remplissez-le depuis l'enregistrement source et faites un upsert dessus. Le chargement devient idempotent : relance-le et il met a jour au lieu de dupliquer.
  • Traitez les references circulaires en deux passes. Les auto-lookups comme Account.ParentId, et les paires qui se pointent mutuellement, ne peuvent pas etre satisfaites en une insertion. Chargez les enregistrements avec le lookup vide, puis lancez une seconde passe qui ne renseigne que ce lookup.
  • Remappez la propriete. Owner et tout lookup vers User ne se resoudront pas : les noms d'utilisateur en sandbox recoivent un suffixe et vos utilisateurs de production peuvent y manquer. Remappez-les avant le chargement.
  • Les jonctions en dernier. Ne chargez un objet de jonction qu'une fois ses deux maitres crees.
  • Contournez l'automatisation, ne la desactivez pas. Triggers, flows, regles de validation et de doublons se declenchent pendant le chargement. Un interrupteur de contournement consulte par votre automatisation vaut mieux que deployer des desactivations.

Comment anonymiser sans rendre les donnees inutiles ?

Un masquage qui produit du bruit vaut le non-masquage : personne ne fait confiance a un test tombe sur des donnees absurdes. Adaptez la technique au champ :

  • Pseudonymes deterministes pour tout ce qui sert aux jointures, au rapprochement ou au dedoublonnage. La meme entree doit toujours donner la meme sortie, pour qu'un client reste un client sur tous les objets.
  • Melange a l'interieur de la colonne quand la distribution compte plus que la valeur, par exemple les tranches de chiffre d'affaires ou les dates de cloture sur lesquelles vous reportez.
  • Suppression pure et simple pour les champs qu'aucun test ne touche. Les notes libres, les descriptions et les pieces jointes sont la ou les donnees personnelles se cachent reellement.
  • Neutralisez tout ce qui peut sortir. E-mails, numeros de telephone et identifiants externes utilises par les integrations doivent etre reecrits vers des valeurs qui ne peuvent atteindre personne, et le parametre de delivrabilite e-mail de la sandbox verifie avant le premier chargement.

Salesforce propose Anonymize for Salesforce, et Gearset, Odaseva et Flosum vendent des outils de seeding avec masquage integre. Quel que soit l'outil, le jeu de regles doit etre valide une fois, par ecrit, par le responsable de la protection des donnees.

Que se passe-t-il quand le schema change ?

C'est la partie que presque personne ne traite, et c'est pourquoi la plupart des jeux meurent en un trimestre. Une definition de seeding est une photo figee de votre schema : listes de champs, valeurs de picklist, champs obligatoires, regles de validation. Livrez un nouveau champ obligatoire et tous les chargements suivants echouent.

Traitez le jeu de donnees comme du code source :

  • Versionnez la definition dans le depot, a cote des metadonnees dont elle depend, pour qu'un changement de schema et son changement de seeding arrivent dans la meme pull request.
  • Derivez les colonnes d'un appel describe plutot que de figer une liste manuelle, afin que les nouveaux champs ne disparaissent pas en silence.
  • Executez le chargement en CI contre une scratch org sur toute pull request touchant objets, champs ou regles de validation. Un chargement en echec est un echec de build legitime : il signale que vous venez de casser la creation de donnees.
  • Regenerez apres chaque refresh. Les valeurs de picklist sont renommees et des record types disparaissent ; un jeu correct en mars est une file d'erreurs de validation en juin.

Dans Serpent, une operation de donnees est une action de pipeline a part entiere plutot qu'une corvee manuelle, ce qui permet au chargement de vivre dans le meme pipeline que le deploiement qu'il soutient.

Alignez enfin la cadence sur vos releases : chaque iteration pour les sandboxes de developpement, chaque campagne de tests pour la recette, toujours apres un refresh. Comme le chargement est idempotent et versionne, c'est une execution de pipeline et non un projet. D'autres guides DevOps Salesforce.

FAQ

Quel volume de donnees une sandbox alimentee doit-elle contenir ?

De quoi couvrir chaque record type, parcours et cas limite, en general quelques centaines d'enregistrements relies. Le volume ne compte que pour les tests de charge.

Puis-je simplement utiliser Data Loader ?

Oui, pour un petit jeu. Vous prenez alors en charge vous-meme l'ordre de chargement, le remappage des identifiants et le masquage, et vous les refaites a la main a chaque refresh.

Un refresh de sandbox conserve-t-il les donnees chargees ?

Non. Un refresh remplace la sandbox : tout ce que vous aviez charge disparait. Prevoyez le rechargement comme etape standard apres refresh.

Articles similaires

Curieux de livrer plus vite avant de vous lancer ? Parlons-en

Sans engagement.