Spring til hovedindhold

Hvordan man tester Unity gemme migreringer mod historiske spiller stater

Original Persistium migration graf viser historiske gemme checkpoints, transformation trin, og inspicerede resultater.

En praktisk, lokal-første proces til at øve Unity spare migreringer mod reelle historiske tilstand former, før en opdatering når spillere.

Clean- account test går glip af den vigtige defekt

En ny Unity build kan se perfekt ud, når den starter med en tom profil. En frisk konto har ingen pensionerede felter, halvfærdige quests, cache katalog referencer, gamle beholdning stakke, afbrudt køb, eller værdier, der var gyldige under et tidligere regelsæt. Det viser derfor kun, at det nye format kan skabe en ny tilstand. Det siger meget lidt om, hvorvidt spillet kan sikkert bære en spiller fra gårsdagens verden ind i dagens én.

Migration arbejde bør begynde fra et stærkere spørgsmål: kan denne nøjagtige historiske tilstand indtaste den nuværende bygning, bevare den betydning, der stadig betyder noget, og enten blive gyldig nuværende tilstand eller mislykkes på en måde, der er nyttig at diagnosticere? Det er et produkt spørgsmål så meget som en serializer spørgsmål. Et felt kan desertialize med succes, mens stadig krænker en progression regel, peger på manglende indhold, eller ændre en købsret. Indlæser bytes er ikke nok.

Denne artikel beskriver en lokal-første prøveproces. Det er bevidst ikke et løfte om, at et værktøj kan forstå hver Unity serialisering setup, backend, eller platform integration. Unity datamodeller varierer, og et spil kan tilføje sin egen kryptering, cloud sync, binær format, eller brugerdefinerede adaptere. Den holdbare del er test disciplin: bevare historiske figurer, kopiere dem før mutation, gøre migration stien eksplicit, og kontrollere spil invariants efter hver grænse.

Byg en historisk tilstand corpus

Behandl gamle gemmer som en versioneret corpus, ikke som løse filer passeret rundt i chat. Hver opstilling har brug for en stabil identifikator, den version, der producerede det, en kort scenario etiket, en format erklæring, og en privacy classification. Scenariet etiket betyder noget, fordi en migration suite bør omfatte meningsfulde tilstande, ikke bare tilfældige JSON. Eksempler omfatter en ny spiller, en spiller ved en kapitelgrænse, en opgørelse på sin stak grænse, en afbrudt tutorial, en gammel begivenhed belønning, en bruger med valgfri kosmetisk indhold, og en profil, der bevidst indeholder en ugyldig arv kombination.

Brug uforanderlige arbejdseksemplarer. Testløberen bør aldrig overskrive kildelisten, mens du forsøger at migrere. Kopiér fikseringen til en midlertidig arbejdsmappe, registrer dens checksum eller indhold hash, kør adapteren, og beholder den resulterende output separat. Dette gør et overraskende resultat til beviser en anden kan spille igen. Det forhindrer også en test fra stille og roligt at forbedre sit eget input, indtil det oprindelige problem forsvinder.

Hold spillerdata fra produktion ude af en generel mappe med testdata til udvikling. En historisk testdatasamling kan være syntetisk, bruges med samtykke, være omhyggeligt maskeret eller genereres ud fra deterministiske scenarier. Det afgørende er, at den bevarer de strukturelle og semantiske grænsetilfælde, der har betydning. Persondatabeskyttelse må ikke være en eftertanke: fjern direkte identifikatorer, enhedsidentifikatorer, kontaktoplysninger, betalingstokens, rå kvitteringer og hemmeligheder, før testdata bliver bredt tilgængelige.

Tegn migreringsgrafen før du skriver en konverter

Version numre er ikke en migration plan. Et spil kan flytte fra 1 til 2, 2 til 3, og 3 til 4, derefter støder på en spiller, der har sprunget direkte fra 1 til 4. Det kan sende en hotfix, der ændrer kun en nested lagerrekord, eller trække et felt, som gammelt indhold stadig forventer. En graf gør disse valg synlige: hver node er en save skema eller semantic version; hver kant er en eksplicit transformation eller afstødning eller kant har en forstøblet, eller kant, og en forstøbelse.

For hver understøttet start version, afgøre, om spillekæder tilstødende transformerer, bruger en direkte transformation, eller kræver en service-side opgradering, før klienten indlæses. Lad ikke skippede versioner til hvad der sker, når felter er fraværende. En kæde kan være sikrere, når hvert trin er lille og testet. En direkte transformation kan være sikrere, når mellemliggende formater aldrig var beregnet til at være observerbar. Begge tilgange har brug for klart ejerskab og repeterbare inventar.

Original migration graf med fem state noder forbundet med eksplicit understøttet konvertering stier.
En migreringsgraf gør versionsspring, understøttede stier og inspektionspunkter synlige, før koden skjuler dem.

Grafen bør omfatte mere end den serialiserede type. Registrer afhængigheder i indholdskataloget, konfigurationsversioner, feature flag, der påvirker fortolkningen, og den aktuelle programversion. En gemme kan være syntaktisk aktuel endnu ugyldig, fordi en refereret element ikke længere eksisterer eller en regel ændret mening. Det er kompatibilitet grænser, ikke irriterende kant tilfælde.

Gør save- load runde ture observerbar

Når en fiksering kommer ind i migreringsstien, udfører en fuld rundtur: indlæse det historiske input, migrere det, konstruere In- game model, gemme det ved hjælp af den nuværende forfatter, derefter indlæse den aktuelle output igen. Den første belastning kontrollerer, om en historisk rekord kan indtaste systemet. Den anden belastning kontrollerer, om den nuværende forfatter skabte et stabilt, selv- konsistent resultat. Sammenlign staten efter den første og anden belastning i henhold til semantiske regler, ikke kun rå byte lighed.

Rå lighed er ofte den forkerte påstand. Nye standardværdier kan tilføjes, felt orden kan ændre, tidsstempler kan blive frigjort, og samlinger kan modtage stabil bestilling. Definer en normalizer for værdier, der er bevidst non- semantic, derefter sammenligne resten. Normalizer selv fortjener gennemgang; det må ikke blive en tæppe ignore liste, der skjuler reelle tab. En god sammenligning rapporter, som felter blev tilføjet, fjernet, transformeret, eller bevidst ignoreret.

Testresultatet bør navngive den første ugyldige tilstand. Hvis en migrationskæde har tre overgange, skal du ikke rapportere kun, at den endelige belastning mislykkedes. Fange staten efter hvert checkpoint, validere det, og stoppe ved den tidligste grænse, der overtræder en invariant. At lokalisering konverterer en vag "gamle gemme brudt" rapport til en specifik migration kant, fiksering, og stat forskel.

Ekspres-specifikke invarianter

En generel migration sele kan ikke vide, hvad progression betyder i et bestemt spil. Spillet skal give sine egne invariants. Skriv dem på et sprog, der forbinder til spillerens resultater: et niveau er inden for det aktuelle område; en lagermængde er ikke-negativ og afgrænset; hvert element har en kendt definition eller en eksplicit arv fallback; en afsluttet tutorial forbliver afsluttet; valuta er finite; en søgen reference tilhører et aktuelt katalog; en rettighed er unik; en verden frø og genereret verden stat aftale.

Separate invariants i lag. Strukturelle invariants besvare, om nødvendige felter og typer eksisterer. Referencemæssige invariants besvare, om ID 'er peger på kendte definitioner. Domæne invariants besvare, om værdier adlyder spillets regler. Sikkerhed invariants besvare, om data er begrænsede, afgrænset og sikkert at vise. Når en opstilling mislykkes, laget fortæller holdet, om det har brug for en serializer ændring, katalog adapter, regelfastsættelse beslutning, eller opsving politik.

Brug deterministiske mutationer til at gøre corpus arbejde hårdere. Start fra en kendt stativ og bevidst fjerne et felt, duplikere et inventar ID, erstatte en katalog reference, springe en version, ombestille en aktionsliste, eller ændre en grænse mængde. Hver mutation bør have et forventet resultat: migrere med en dokumenteret standard, afvise med en diagnostisk kategori, karantæne for inddrivelse, eller kræve en ejer- godkendt data reparation. "Det ikke nedbrud" er ikke et tilstrækkeligt forventet resultat.

Reducer en fejlgemning uden at miste fejlen

Store player stater er vanskelige at forstå. Hvis en fiksering indeholder hundredvis af felter og en migration mislykkes, kan en udvikler bruge timer på at læse ikke-relaterede data. Counterexample minimering reducerer fikseringen mens den krænkede invariant bevares. Fjern en felt gruppe, prøve den samme deterministiske migration, og holde fjernelse kun, når fejlen stadig opstår. Derefter partition samlinger, krympe værdier mod grænser, og reducere handling historie, hvis genspil adfærd betyder noget.

Original counterexample- reduktion visuelle viser en stor tilstand indsnævret gennem repeterbare partitioner i en minimal regression fiksering.
Reduktionsprocessen bevarer den invariant fiasko samtidig med at fjerne ikke-relateret tilstand.

Reduktion kræver reproducerbarhed. Lås fiksturet hash, migration version, adapter version, deterministiske frø, relevante konfiguration snapshot, og forventet invariant. Hvis miljøet ændrer sig under hvert forsøg, kan en reducer producere en mindre tilstand for et andet problem. Hold en replay manifest med disse indgange og det observerede resultat. Output er ikke blot en mindre fil; det er en regression tilfælde en anden kan udføre.

Genererede regressionsinventar bør indtaste den samme gennemgang sti som håndskrevne dem. Giv hver stativ et stabilt navn, en kort forklaring på den fejl, invariant det bevarer, og en forventet klassificering. En regressionsstativ er værdifuld, fordi det gør en tidligere overraskende grænse rutine. Det bør ikke blive en skjult kilde til produktion spiller data eller en catch- alle for uforklarlige fejl.

Sæt prøven i CI uden at gøre det støjende

Kør en hurtig repræsentativ delmængde på alle relevante ændringer: nuværende migrationskanter, high- risk historiske stater, og et lille sæt af deterministiske mutationer. Kør den fulde corpus på et planlagt job, frigive kandidat, eller ændring, der rører serialisering, progression, katalog fortolkning, cloud sync, eller saveformat kode. Skjul ved fiksering familie eller migration kant snarere end at sende hver test gennem en lang sekvens.

CI output skal være kortfattet, men inspicerbar. Rapportér fiksturet ID, start og mål versioner, migration kant, invariant lag, første ugyldige checkpoint, og en sti til den redigerede artefakt eller diff. undgå at udskrive fuld profil indhold i logfiler. Når en fejl er ny, bevare de minimale oplysninger, der er nødvendige for at reproducere det lokalt; når det forventes, registrere, at klassificering så en udgivelse ikke lydløst normalisere en kendt risiko.

Release beslutningen bør angive, hvad beviserne betyder. Passing migration test understøtter en afgrænset påstand: de testede corpus og erklærede stier opført som forventet i dette miljø. De ikke bevise hver spiller gemme, enhed, eller ekstern tjeneste vil opføre sig identisk. Teams stadig har brug for rollback planer, customer- support håndtering, og overvågning, der respekterer privatlivets fred.

Praktisk tjekliste

  • Hold en versioneret historisk corpus med scenarieetiketter og fortrolighedsklassifikationer.
  • Kopier input før migration og bevare hash for kilde og output artefakter.
  • Tegn understøttede migrationskanter, herunder skipped- version politik og eksplicitte afslag.
  • Validér strukturelle, referencemæssige, domæne og sikkerhedsinvarianter efter hvert checkpoint.
  • Round- trip migreret output gennem den nuværende forfatter og læser.
  • Brug deterministiske mutationer til at teste manglende felter, duplikater, pensioneret indhold og grænseværdier.
  • Reducer reproducerbare fejl i gennemgåede regressionsarmaturer med replay manifester.
  • Kør risikofokuserede delsæt kontinuerligt og den fulde corpus før release-følsomme ændringer.
  • Hold logfiler og artefakter redigeret; ikke gøre CI til en afspilningsdataarkiv.

Ofte stillede spørgsmål

Har vi brug for reel spiller sparer for at teste migration?

Nej. Rigtige historiske figurer er nyttige, men corpus kan være syntetisk eller omhyggeligt redigeret. Hvad der betyder er at bevare de vanskelige statslige kombinationer: pensioneret indhold, lang progression, afbrudt overgange, valgfrie data, og værdier ved meningsfulde grænser. Hvis produktionsdata bruges til at opdage en kant tilfælde, udlede en sikker stativ, der bevarer kun ejendommen under test.

Skal alle gamle versioner forblive understøttet for evigt?

Ikke nødvendigvis. Støtte er et produkt og operationelle beslutning. Det vigtigste er at gøre grænsen eksplicit: hvilke versioner migrere, som kræver en tidligere opdatering, som er afvist, og hvordan spilleren er informeret. En udokumenteret utilsigtet sti er den mindst sikre mulighed, fordi det hverken er pålideligt understøttet eller klart afvist.

Kan en serializer test erstatte gameplay tests?

Nej. Serializer test fastslår, at data kan læses og skrives i henhold til deklarerede former. Gameplay og domæne tests fastslår, at den resulterende tilstand giver mening i det nuværende regelsæt. En robust migration prøve har brug for både, plus en gennemgang af indhold og konfiguration referencer, der påvirker betydningen af gemte værdier.

Hvad er Persistium rolle her?

Persistium er en in-development local-first pålidelighed produkt familie. Vejledningen i denne note er praktisk engineering rådgivning, ikke en påstand om, at en offentlig Persistium produkt er tilgængelig, eller at det har diagnosticeret reelle kundedata. Dens Kontinuitet retning udforsker den slags eksplicitte migration, spil, sammenligning, og reduktion workflow beskrevet ovenfor.

Relateret systemUdforsk Persistium