MetricKit-Diagnose-Payloads treffen nicht im Takt der Commits ein. Selbst wenn heute nur eine Zeile im Parser geändert wird, zeigt sich möglicherweise erst Tage später anhand eines echten Absturz- oder Hängerberichts, dass Felder verloren gegangen sind. Robuster ist es, bereits erfasste Payloads zu anonymisieren, zu normalisieren und als feste Testdaten zu speichern. So wird auf dem Cloud-Mac bei jedem Commit derselbe Eingabesatz wiederholt verarbeitet. Damit wird die Diagnosepipeline selbst geprüft, statt auf das nächste sporadische Ereignis zu warten.
Testgrenzen klar definieren
Feste Testdaten eignen sich für vier Prüfebenen: ob sich das ursprüngliche JSON einlesen lässt, ob Systemfelder korrekt auf das interne Modell abgebildet werden, ob vertrauliche Inhalte entfernt wurden und ob fehlerhafte Eingaben kontrolliert behandelt werden. Sie können weder belegen, dass das System tatsächlich Payloads erzeugt, noch die Prüfung der Callbacks auf einem Gerät ersetzen.
Es empfiehlt sich, den Empfang der Daten von ihrer fachlichen Verarbeitung zu trennen. Die Empfangsschicht sollte lediglich jsonRepresentation() abrufen, die Daten in ein geschütztes Verzeichnis schreiben und zur Übertragung einreihen. Die Parserschicht nimmt Data entgegen und gibt eine interne Struktur aus, die nicht von MetricKit-Typen abhängt. Unit-Tests rufen nur diese Schicht auf, sodass das Test-Target keine Systemobjekte nachbilden muss.
Der Wert von Testdaten liegt nicht darin, einen einzelnen erfolgreichen Parse-Vorgang nachzuahmen. Sie fixieren vielmehr den Eingabevertrag, damit sich nach jeder Parseränderung beantworten lässt, welche Felder sich geändert haben und welche Informationen verworfen wurden.
Normalisierte, versionierbare Testdaten erstellen
Unverarbeitete Payloads können Bundle-Kennungen, Geräteinformationen, Zeitangaben, Stack-Symbole und lokale Pfade enthalten. Sie dürfen nicht direkt eingecheckt werden. Das Original sollte zunächst in einer zugriffsbeschränkten Umgebung aufbewahrt werden. Anschließend wird eine normalisierte Kopie für das Repository erzeugt: Zeitangaben werden durch feste Werte ersetzt, Kennungen durch Testwerte und Pfade durch $APP beziehungsweise $HOME. Adressen im Aufruf-Stack behalten ihr Format, enthalten aber keine echten Adressen mehr.
Das interne Format kann um ein Feld namens schema ergänzt werden. Die ursprüngliche MetricKit-Version darf dabei jedoch nicht verändert werden. Das Verzeichnis wird nach Diagnosetyp gegliedert:
Tests/Fixtures/MetricKit/
├── crash/basic.json
├── crash/missing-stack.json
├── hang/main-thread.json
├── disk-write/threshold.json
└── malformed/truncated.json
Jede Datei sollte genau eine Bedingung abbilden. Enthält eine Datei gleichzeitig einen Absturz, einen Hänger und eine Datenträgeranomalie, lässt sich die Ursache eines Fehlers nur schwer eingrenzen. Der Dateiname beschreibt die Eingabe, nicht das erwartete Ergebnis. Die Sollwerte gehören in den Testcode, damit bei der Prüfung leichter auffällt, wenn Assertions beiläufig mitgeändert wurden.
Vor den Tests eine Strukturprüfung ausführen
Eine kostengünstige Prüfung mit jq vor dem Kompilieren der Tests erkennt ungültiges JSON, fehlende Versionen und nicht anonymisierte Pfade frühzeitig. Bei diagnostics im folgenden Beispiel handelt es sich um das normalisierte Array des Teams. Es wird nicht vorausgesetzt, dass das ursprüngliche System-Payload dieselbe Struktur besitzt.
set -euo pipefail
root="Tests/Fixtures/MetricKit"
find "$root" -name '*.json' -print0 |
while IFS= read -r -d '' file; do
jq -e '
type == "object" and
.schema == 1 and
(.diagnostics | type == "array") and
all(.diagnostics[];
(.kind | type == "string") and
(.timestamp | type == "string") and
(.stackID | type == "string")
)
' "$file" >/dev/null
if grep -E '/Users/|/private/var/|[A-F0-9]{16,}' "$file"; then
echo "fixture contains unnormalized data: $file" >&2
exit 1
fi
done
Die Strukturprüfung sollte nicht sämtliche Systemfelder vorschreiben, da neue optionale Felder sonst unnötige Fehler auslösen. Geprüft werden nur die Schlüssel, von denen die interne Verarbeitung tatsächlich abhängt. Der Decoder sollte unbekannte Felder ignorieren.
Parservertrag mit Positiv- und Negativfällen abdecken
Es sollten mindestens ein gültiger Eingabesatz und drei fehlerhafte Eingabesätze vorhanden sein. Entscheidend ist nicht allein, dass kein Fehler ausgelöst wird. Die Ausgabe muss weiterhin für Aggregation, Alarmierung und Fehleranalyse nutzbar sein.
| Testdaten | Erwartetes Verhalten | Darf nicht passieren |
|---|---|---|
| Vollständiger Absturz | Typ, Zeit und Stack-Kennung ausgeben | Ursprünglichen lokalen Pfad speichern |
| Leeres Diagnose-Array | Leeres Ergebnis zurückgeben | Als Decodierungsfehler behandeln |
| Fehlender Aufruf-Stack | Als unvollständig kennzeichnen | Leeren Stack als reguläre Daten ausgeben |
| Abgeschnittenes JSON | Klassifizierbaren Fehler zurückgeben | Prozess unmittelbar beenden |
| Unbekannter Typ | Unbekannten Enum-Wert erfassen | Gesamtes Payload-Batch verwerfen |
Internes Modell statt des vollständigen JSON prüfen
Vollständige Snapshots reagieren empfindlich auf Änderungen der Feldreihenfolge und irrelevanter Metadaten. Assertions sollten sich vorrangig auf die Anzahl und Typen der Diagnosen, stabile Kennungen sowie das Ergebnis der Anonymisierung beziehen. Ein Snapshot des formatierten JSON ist nur dann sinnvoll, wenn die normalisierte Ausgabe zwischen Systemen ausgetauscht wird. Auch Fehler sollten als vergleichbare Enum-Werte vorliegen, beispielsweise invalidJSON, missingRequiredField oder unsupportedDiagnostic, statt ausschließlich veränderliche Meldungen in natürlicher Sprache zu vergleichen.
In die Cloud-Mac-CI integrieren
Auf einem Cloud-Mac von VMRunner wird die Prüfung der Fixtures vor den Unit-Tests ausgeführt. Nicht interaktive Tasks müssen außerdem ein festes Arbeitsverzeichnis verwenden. Eine mögliche Reihenfolge lautet: Code auschecken, Strukturprüfung ausführen, Parser-Unit-Tests starten, Testergebnisse erzeugen und abschließend prüfen, ob im Arbeitsverzeichnis nicht eingecheckte Änderungen an den Testdaten entstanden sind.
Änderungen an den Testdaten müssen separat geprüft werden. Kommen neue Systemfelder hinzu, ist zunächst zu klären, ob der Parser sie verarbeiten muss. Falls ja, wird das interne schema aktualisiert und zusammen mit Migrationstests eingecheckt. Falls nein, bleibt die Decodierung tolerant. Baseline-Dateien dürfen in der CI nicht automatisch von Skripten überschrieben werden. Andernfalls könnte ein tatsächlicher Feldverlust durch ein neues, aber fehlerhaftes Ergebnis „genehmigt“ werden.
Prüfliste vor dem Merge
- Die ursprünglichen Payloads wurden außerhalb des Repositorys anonymisiert.
- Jede Testdatei deckt genau eine Diagnosebedingung ab.
- Gültige Daten, leere Werte, fehlende Felder, abgeschnittene Daten und unbekannte Typen sind durch Tests abgedeckt.
- Unbekannte optionale Felder führen nicht dazu, dass das gesamte Batch fehlschlägt.
- Lokale Pfade, lange Kennungen und Benutzerinhalte können die Strukturprüfung nicht passieren.
- Parserfehler liefern stabile Fehlerkategorien zurück.
- Änderungen an Fixtures und Parser werden gemeinsam geprüft.
Sind diese Vorgaben umgesetzt, wird die Verarbeitung von MetricKit-Diagnosen von einem nachträglichen Versuch nach Dateneingang zu einem normalen, reproduzierbaren Engineering-Test. System-Payloads müssen weiterhin auf Geräten geprüft werden, doch Parsing, Anonymisierung und Kompatibilität hängen nicht mehr von zufällig eintreffenden Berichten ab.
Häufig gestellte Fragen
Ersetzen MetricKit-Fixtures einen Test auf echten Geräten?
Nein. Fixtures prüfen Decoder, Bereinigung und Abbildung. Ob das Betriebssystem Diagnosen tatsächlich erzeugt und zustellt, muss weiterhin mit kontrollierten Gerätetests und Produktionsbeobachtung verifiziert werden.
Sollte unverändertes MetricKit-JSON im Repository liegen?
In der Regel nicht. Bewahren Sie bereinigte Rohdaten zugriffsbeschränkt auf und versionieren Sie nur normalisierte Fixtures ohne Nutzerkennungen, lokale Pfade oder vertrauliche Anwendungsdaten.
Muss ein unbekanntes neues Feld die CI stoppen?
Normalerweise nicht. Zusätzliche optionale Felder sollten toleriert werden. Fehlen jedoch intern erforderliche Angaben wie Diagnoseart, Zeitpunkt oder Stapelkennung, muss der Test fehlschlagen.
Den nächsten Build auf einem exklusiven Cloud-Mac ausführen
Wählen Sie Modell, Standort und Abrechnungszeitraum. Konfiguration und Preise in USD werden vor der Bestellung vollständig angezeigt; der Verfügbarkeitsstatus wird in Echtzeit über die Konsole ermittelt.