Les tests de compte propre manquent le défaut important
Une nouvelle construction Unity peut sembler parfaite lorsqu'elle commence avec un profil vide. Un nouveau compte n'a pas de champs à la retraite, des quêtes à moitié terminées, des références de catalogues en cache, des piles d'inventaire anciennes, des achats interrompus, ou des valeurs qui étaient valides sous un ensemble de règles antérieur. Il prouve donc seulement que le nouveau format peut créer un nouvel état.
Le travail de migration devrait commencer à partir d'une question plus forte: cet état historique exact peut-il entrer dans la construction actuelle, préserver le sens qui compte encore, et soit devenir l'état courant valide ou échouer d'une manière qui est utile pour diagnostiquer? C'est une question de produit autant qu'une question de serializer. Un champ peut désérialiser avec succès tout en violant une règle de progression, pointant vers le contenu manquant, ou changer un droit d'achat.
Cet article décrit un processus de première répétition locale. Il n'est délibérément pas une promesse qu'un outil peut comprendre chaque configuration de sérialisation Unity, backend, ou intégration de plate-forme. Les modèles de données Unity varient, et un jeu peut ajouter son propre chiffrement, synchronisation cloud, format binaire ou adaptateurs personnalisés. La partie durable est la discipline de test: préserver les formes historiques, copier avant la mutation, rendre le chemin de migration explicite, et vérifier les invariants de jeu après chaque limite.
Construire un corpus d'état historique
Chaque installation a besoin d'un identifiant stable, de la version qui l'a produit, d'une étiquette de scénario courte, d'une déclaration de format et d'une classification de confidentialité. L'étiquette de scénario compte parce qu'une suite de migration doit inclure des états significatifs, et non pas seulement au hasard JSON. Par exemple, un nouveau joueur, un lecteur à une limite de chapitre, un inventaire à sa limite de pile, un tutoriel interrompu, une ancienne récompense d'événement, un utilisateur avec du contenu cosmétique optionnel et un profil qui contient intentionnellement une combinaison de legs invalides.
Utilisez des copies de travail immuables. Le coureur de test ne devrait jamais écraser le fixture source lors d'une tentative de migration. Copiez le fixture dans un répertoire de travail temporaire, enregistrez son checksum ou son hash de contenu, exécutez l'adaptateur et conservez la sortie résultante séparément. Cela transforme un résultat surprenant en preuve que quelqu'un d'autre peut rejouer.
Un corpus historique peut être synthétique, consenti, soigneusement expurgé, ou généré à partir de scénarios déterministes. La clé est qu'il conserve les cas de bords structuraux et sémantiques qui comptent. La vie privée n'est pas une post-réflexion : supprimer les identifiants directs, les identifiants de périphérique, les informations de contact, les jetons de paiement, les reçus bruts et les secrets avant qu'un appareil ne devienne largement accessible.
Dessiner le graphique de migration avant d'écrire un convertisseur
Les numéros de version ne sont pas un plan de migration. Un jeu peut passer de 1 à 2, 2 à 3 et 3 à 4, puis rencontrer un joueur qui a sauté directement de 1 à 4. Il peut expédier un hotfix qui ne change qu'un enregistrement d'inventaire imbriqué, ou retirer un champ que l'ancien contenu attend encore. Un graphique rend ces choix visibles : chaque nœud est un schéma de sauvegarde ou une version sémantique ; chaque bord est une transformation explicite ou un rejet intentionnel ; chaque bord a des conditions préalables et postconditions.
Pour chaque version de démarrage prise en charge, décidez si les chaînes de jeu adjacentes se transforment, utilisent une transformation directe, ou nécessite une mise à niveau côté service avant que le client charge. Ne laissez pas les versions évanouies à tout ce qui arrive lorsque les champs sont absents. Une chaîne peut être plus sûre lorsque chaque étape est petite et testée. Une transformation directe peut être plus sûre lorsque les formats intermédiaires n'ont jamais été conçus pour être observables.

Le graphique doit inclure plus que le type sérialisé. Enregistrer les dépendances du catalogue de contenu, les versions de configuration, les drapeaux de fonction qui affectent l'interprétation, et la version de l'application actuelle. Un sauvegarde peut être syntaxiquement courant mais non valide parce qu'un élément référencé n'existe plus ou une règle a changé de sens.
Faire des voyages aller-retour d'économie observables
Une fois qu'un fixture entre dans le chemin de migration, effectue un aller-retour complet : chargez l'entrée historique, migrez-le, construisez le modèle en jeu, sauvegardez-le en utilisant l'auteur courant, puis chargez à nouveau cette sortie courante. La première charge vérifie si un enregistrement historique peut entrer dans le système. La seconde charge vérifie si l'auteur courant a créé un résultat stable et autocohérent.
L'égalité brute est souvent la mauvaise assertion. De nouveaux défauts peuvent être ajoutés, l'ordre des champs peut changer, les horodatages peuvent être rafraîchis et les collections peuvent recevoir une commande stable. Définissez un normalisateur pour des valeurs qui sont intentionnellement non sémantiques, puis comparez le reste. Le normalisateur lui-même mérite d'être revu; il ne doit pas devenir une liste de couverture qui cache la perte réelle.
Si une chaîne de migration a trois transitions, ne déclarez pas seulement que la charge finale a échoué. Capturez l'état après chaque point de contrôle, validez-le, et arrêtez à la limite la plus ancienne qui viole un invariant. Que la localisation convertit un vague rapport de sauvegarde vieux cassé en un bord de migration spécifique, fixe et différence d'état.
Invariants spécifiques au jeu Express
Un harnais général de migration ne peut pas savoir ce que signifie la progression dans un jeu particulier. Le jeu doit fournir ses propres invariants. Ecrivez-les dans un langage qui se connecte aux résultats du joueur: un niveau est dans la plage actuelle; une quantité d'inventaire est non négative et limitée; chaque élément possédé a une définition connue ou un retour explicite à l'héritage; un tutoriel terminé reste terminé; la monnaie est finie; une référence de quête appartient à un catalogue courant; un droit est unique; une semence mondiale et un état mondial généré sont d'accord.
Les invariants de domaine répondent à la question de savoir si les valeurs obéissent aux règles du jeu. Les invariants de sécurité répondent à la question de savoir si les données sont finies, limitées et sûres à afficher. Lorsqu'un montage échoue, le calque indique à l'équipe s'il a besoin d'un changement de sérialiste, d'un adaptateur de catalogue, d'une décision de règlement ou d'une politique de récupération.
Utilisez des mutations déterministes pour rendre le corpus plus dur. Commencez par un montage connu et retirez délibérément un champ, dupliquez un ID d'inventaire, remplacez une référence de catalogue, sautez une version, réarrangez une liste d'action ou modifiez une quantité limite. Chaque mutation devrait avoir un résultat attendu : migrer avec un défaut documenté, rejeter avec une catégorie de diagnostic, quarantaine pour la récupération ou exiger une réparation de données approuvée par le propriétaire.
Réduire une sauvegarde en panne sans perdre le bogue
Si un fixture contient des centaines de champs et qu'une migration échoue, un développeur peut passer des heures à lire des données non liées. La minimisation de contre-exemple réduit le fixture tout en préservant l'invariant violé. Enlever un groupe de champs, réessayer la même migration déterministe, et ne garder l'enlèvement que lorsque l'échec se produit encore.

La réduction nécessite une reproductibilité. Verrouiller le hachage du fixture, la version de migration, la version d'adaptateur, la graine déterministe, l'instantané de configuration pertinent et l'invariant attendu. Si l'environnement change au cours de chaque réessayer, un réducteur peut produire un état plus petit pour un problème différent.
Les correctifs de régression générés devraient entrer dans le même chemin d'examen que les correctifs d'auteurs manuels. Donnez à chaque fixture un nom stable, une courte explication de l'échec, l'invariant qu'elle conserve et une classification attendue. Un correctif de régression est utile parce qu'il fait une routine de limites auparavant surprenante.
Mettre la répétition en CI sans la rendre bruyante
Exécutez un sous-ensemble représentatif rapide sur chaque changement pertinent : les bords de migration actuels, les états historiques à haut risque et un petit ensemble de mutations déterministes. Exécutez le corpus complet sur un travail programmé, relâchez le candidat ou le changement qui touche la sérialisation, la progression, l'interprétation du catalogue, la synchronisation nuageuse ou le code de format de sauvegarde.
La sortie de l'IC doit être concise mais inspectable. Signaler l'ID de l'installation, les versions de début et de cible, le bord de migration, la couche invariante, le premier point de contrôle invalide, et un chemin vers l'artefact ou la diff. Éviter d'imprimer le contenu complet du profil dans les journaux.
La décision de libération doit indiquer ce que signifie la preuve. Passer des tests de migration soutient une revendication limitée: le corpus testé et les chemins déclarés se sont comportés comme prévu dans cet environnement. Ils ne prouvent pas que chaque joueur sauvegarde, appareil, ou service externe se comportera de manière identique.
Liste de contrôle pratique
- Conservez un corpus historique en version avec des étiquettes de scénarios et des classifications de confidentialité.
- Copier les entrées avant la migration et préserver les hachages pour les artefacts source et sortie.
- Dessiner les bords de migration pris en charge, y compris la politique de la version ignorée et les refus explicites.
- Valider les invariants de structure, de référence, de domaine et de sécurité après chaque point de contrôle.
- La sortie aller-retour migre par l'auteur et le lecteur actuels.
- Utilisez des mutations déterministes pour tester les champs manquants, les enregistrements en double, le contenu retiré et les valeurs limites.
- Réduire les défaillances reproductibles dans les correctifs de régression examinés avec des manifestes de replay.
- Exécuter des sous-ensembles axés sur le risque en continu et le corpus complet avant les changements sensibles à la libération.
- Gardez les journaux et les artefacts expurgés; ne transformez pas l'IC en archive de données de lecteur.
Foire aux questions
Avons-nous besoin d'économies de vrais joueurs pour tester la migration ?
Non. Les formes historiques réelles sont utiles, mais le corpus peut être synthétique ou soigneusement expurgé. Ce qui importe, c'est de préserver les combinaisons d'état difficiles: contenu retiré, longue progression, transitions interrompues, données optionnelles et valeurs aux limites significatives. Si les données de production sont utilisées pour découvrir un cas de bord, dérivez un montage sûr qui ne conserve que la propriété sous test.
Chaque ancienne version devrait-elle rester supportée pour toujours ?
Pas nécessairement. La prise en charge est un produit et une décision opérationnelle. L'important est de rendre la frontière explicite: quelles versions migrent, qui nécessitent une mise à jour antérieure, qui sont rejetées, et comment le lecteur est informé. Un chemin accidentel sans papiers est l'option la moins sûre car il n'est ni supporté fiablement ni clairement refusé.
Un test de serializer peut-il remplacer les tests de gameplay ?
Non. Les tests Serializer établissent que les données peuvent être lues et écrites selon des formes déclarées. Gameplay et les tests de domaine établissent que l'état résultant a un sens dans le jeu de règles actuel. Une répétition de migration robuste a besoin des deux, plus un examen des références de contenu et de configuration qui influencent la signification des valeurs sauvegardées.
Qu'est-ce que le rôle Persistium?
Persistium est une famille de produits de fiabilité première locale en développement. L'orientation dans cette note est des conseils pratiques d'ingénierie, pas une affirmation qu'un produit public Persistium est disponible ou qu'il a diagnostiqué de véritables données client. Sa direction de continuité explore le type de migration explicite, replay, comparaison et réduction de flux de travail décrit ci-dessus.






