Eine auf den ersten Blick harmlose Logik zum Aktualisieren einer Liste kann die CPU dauerhaft auslasten. Zu eng getaktete Timer, doppelte Netzwerkanfragen oder Hintergrundaufgaben können außerdem die Anzahl der Systemaufweckungen erhöhen. Funktionstests schlagen dabei meist nicht fehl, und auch die Codeabdeckung weist nicht auf das Problem hin. Um solche Änderungen vor dem Merge zu erkennen, lässt sich die Testumgebung auf einem cloudbasierten Mac von OVPS festschreiben. Anschließend wird dieselbe Abfolge von Benutzeraktionen mit xctrace aufgezeichnet und mit einer bestätigten Baseline verglichen.
Zuerst festlegen, was die Prüfung misst
Energieverbrauch ist kein einzelner, vom Nutzungsszenario unabhängiger Messwert. Eine im Leerlauf angezeigte Startseite, kontinuierliches Scrollen, Bilddecodierung und Hintergrundsynchronisierung weisen völlig unterschiedliche Ressourcenprofile auf und dürfen nicht in derselben Baseline zusammengefasst werden. Wählen Sie zunächst einen zentralen Ablauf, der 60 bis 120 Sekunden dauert und sich zuverlässig reproduzieren lässt, beispielsweise: App starten, Nachrichtenliste öffnen, drei Bildschirmhöhen scrollen, Detailansicht aufrufen und zurückkehren.
Für jedes Szenario sollten mindestens die folgenden Bedingungen erfasst werden:
- App-Commit und Build-Konfiguration;
- Gerätemodell, Systemversion und Akkuladestand;
- Bildschirmhelligkeit, Netzwerktyp und Status des Stromsparmodus;
- Datenumfang des Testkontos;
- Messdauer sowie Anzahl der Aufwärm- und regulären Durchläufe.
Der Simulator eignet sich dazu, Automatisierungsskripte und die Stabilität der Aktionen zu überprüfen, bildet den Energieverbrauch eines realen Geräts jedoch nicht ab. Die eigentliche Prüfung muss an ein fest zugeordnetes physisches Gerät gebunden sein. Simulatorergebnisse können lediglich als ergänzender Nachweis für die Prozessaktivität dienen.
Verwenden Sie nicht den ersten Durchlauf als Messwert. Beim ersten Start können Datenbankmigrationen, Shader-Vorbereitungen oder das Befüllen von Caches stattfinden. Führen Sie zunächst einen Aufwärmdurchlauf und danach mindestens drei reguläre Aufzeichnungen durch. Verwenden Sie den Median, um Störungen durch sporadische Systemaufgaben auszugleichen.
Cloud-Mac und Zustand des Testgeräts stabilisieren
Auf dem ausführenden Knoten muss die Xcode-Hauptversion festgeschrieben und das Entwicklerverzeichnis ausdrücklich ausgewählt werden. Verlassen Sie sich nicht auf Umgebungsvariablen, die zufällig in einer interaktiven Shell gesetzt sind.
set -euo pipefail
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcodebuild -version
xcrun xctrace version
xcrun xctrace list devices
xcrun xctrace list templates
Die letzten beiden Befehle dienen zugleich als Kompatibilitätsprüfung. Verfügbare Templates und Exportstrukturen können sich zwischen Xcode-Versionen ändern. Das Skript darf daher nicht voraussetzen, dass Energy Log immer vorhanden ist. Wenn das Template fehlt, muss der Ablauf sofort beendet und die Versionsinformation gespeichert werden, statt auf eine bedeutungslose leere Messung zurückzufallen.
Das physische Gerät muss vor Beginn in einen einheitlichen Zustand versetzt werden: nicht benötigte Apps schließen, einen vergleichbaren Akkuladestand sicherstellen, die Normalisierung der Temperatur abwarten, automatische Updates deaktivieren und stabile Netzwerkbedingungen herstellen. Während des Tests dürfen nicht gleichzeitig Archive erstellt, Abhängigkeiten heruntergeladen oder Datenträger bereinigt werden. Zusätzliche Last auf einem gemeinsam genutzten Knoten verfälscht die CPU- und I/O-Messwerte.
Prüfung vor dem Lauf einrichten
Speichern Sie Geräte-UDID, Bundle-ID, Szenarioname und Commit-ID im selben Laufverzeichnis. Der Verzeichnisname muss eindeutig sein, darf aber keine Token oder Signaturmaterialien enthalten, die dadurch in Pfaden oder Protokollen erscheinen würden.
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-${GIT_COMMIT:-local}"
OUT_DIR="artifacts/energy/${RUN_ID}"
mkdir -p "$OUT_DIR"
xcrun simctl list devices > "$OUT_DIR/devices.txt"
xcrun xctrace list templates > "$OUT_DIR/templates.txt"
git rev-parse HEAD > "$OUT_DIR/commit.txt"
Bei einem angeschlossenen physischen Gerät kann der erste Befehl durch den gerätespezifischen Erkennungsbefehl des Teams ersetzt werden. Entscheidend ist nicht die konkrete Befehlsform, sondern dass die Messung bei einem Fehler abgebrochen wird. Andernfalls könnte ein „Gerät nicht verbunden“ fälschlich als „Energieverbrauch gesunken“ gewertet werden.
Reproduzierbare xctrace-Traces aufzeichnen
Starten Sie zunächst den zu messenden Prozess und schließen Sie den Aufwärmdurchlauf ab. Hängen Sie xctrace anschließend anhand des Prozessnamens an. Das folgende Skript setzt voraus, dass Gerät, Prozess und Template ausdrücklich als CI-Parameter übergeben werden:
DEVICE_UDID="${DEVICE_UDID:?missing DEVICE_UDID}"
PROCESS_NAME="${PROCESS_NAME:?missing PROCESS_NAME}"
TRACE="$OUT_DIR/energy.trace"
xcrun xctrace record \
--template "Energy Log" \
--device "$DEVICE_UDID" \
--attach "$PROCESS_NAME" \
--time-limit 90s \
--output "$TRACE"
Nach Beginn der Aufzeichnung führt die UI-Automatisierung die festgelegte Aktionsfolge aus. Das Aktionsskript sollte Accessibility-IDs statt Bildschirmkoordinaten verwenden. Die Testdaten müssen vorab geladen sein, und Netzwerkanfragen sollten möglichst an eine stabile Testumgebung gesendet werden. Schlägt in einem Durchlauf die Anmeldung fehl, verdeckt ein Dialog die Oberfläche oder wird eine vorgesehene Seite nicht erreicht, muss dieser Durchlauf als ungültig markiert werden und darf nicht in den Median einfließen.
Ein erfolgreicher Rückgabestatus von xctrace bedeutet nur, dass ein Trace erzeugt wurde, nicht dass das Szenario korrekt ausgeführt wurde. Zu jeder Aufzeichnung müssen außerdem die UI-Testergebnisse, Start- und Endzeit, eine Zusammenfassung der App-Protokolle sowie eine Markierung für den erfolgreichen Szenarioabschluss gespeichert werden. Fehlt einer dieser Nachweise, muss die Prüfung „Messung ungültig“ melden, statt einen bestandenen Leistungstest auszugeben.
Messwerte exportieren und mit der Baseline vergleichen
Exportieren Sie zunächst die Verzeichnisstruktur des Traces, prüfen Sie, welche Tabellen die aktuelle Xcode-Version bereitstellt, und pflegen Sie anschließend versionsspezifische Auswertungsregeln:
xcrun xctrace export \
--input "$TRACE" \
--toc \
--output "$OUT_DIR/toc.xml"
Ein binärer Trace sollte nicht direkt mit einem fragilen regulären Ausdruck ausgewertet werden. Robuster ist es, für jede Xcode-Hauptversion passende XPath-Ausdrücke oder XML-Parser zu hinterlegen und zusätzlich den ursprünglichen Trace zu archivieren. Die Prüfung kann vier Arten von Veränderungen überwachen: anhaltende CPU-Aktivität, Thread-Aufweckungen, Dichte der Timer-Auslösungen und Netzwerkübertragungsvolumen. Diese Messgrößen dienen als Hinweise für die Fehlersuche und sollten nicht grob zu einem einzigen „Energiewert“ zusammengefasst werden.
Die Baseline basiert auf mehreren normalen Durchläufen mit demselben Gerät, demselben Szenario und demselben Build-Typ. Empfehlenswert ist, den Median der zuletzt bestätigten Version zusammen mit sämtlichen ursprünglichen Einzelwerten zu speichern. Für den Vergleich sollten relative Veränderung und absolute Untergrenze gemeinsam berücksichtigt werden: Eine Verdopplung eines äußerst kleinen Werts ist nicht zwangsläufig technisch relevant.
Abweichungen abgestuft behandeln
Geringfügige Abweichungen sollten zunächst nur eine Warnung auslösen und den Merge nicht blockieren. Erst wenn der Grenzwert wiederholt überschritten wird oder sich CPU-Aktivität und Aufweckungen gleichzeitig verschlechtern, sollte die Prüfung fehlschlagen. Grenzwerte müssen anhand historischer Messdaten des Teams festgelegt werden; ein allgemeiner Prozentwert darf nicht einfach übernommen werden.
Ein Fehlerbericht muss mindestens Commit-ID, Geräte- und Systemversion, die drei Messwerte, Median, Baseline, Änderungsverhältnis, Trace-Pfad und Ergebnis des UI-Szenarios enthalten. So können Entwickler direkt die zugrunde liegenden Nachweise öffnen, statt lediglich die Meldung „Energieverbrauch zu hoch“ zu erhalten.
Vom auffälligen Trace zum Code zurückkehren
Bei dauerhaft erhöhter CPU-Aktivität sollten zuerst Polling auf dem Hauptthread, Bildverarbeitung, wiederholte Layoutberechnungen und nicht beendete Hintergrundwarteschlangen geprüft werden. Steigt die Anzahl der Aufweckungen, sind insbesondere Timer mit kurzen Intervallen, häufige Datenträgerzugriffe, doppelte Benachrichtigungen und nicht zusammengefasste Netzwerk-Wiederholungsversuche zu untersuchen. Bei ungewöhnlicher Netzwerkaktivität sollten paginierte Anfragen, Cache-Treffer, Telemetrie-Batches und die Strategie für erneute Verbindungen kontrolliert werden.
Auch typische Fehlinterpretationen müssen separat ausgeschlossen werden: Temperaturänderungen nach dem Aufladen des Geräts, noch laufender Cache-Aufbau beim ersten Durchlauf, ein geänderter Datenumfang des Testkontos, Unterbrechungen durch Systemdialoge sowie andere gleichzeitig auf dem cloudbasierten Mac ausgeführte rechenintensive Aufgaben. Nach einer Korrektur müssen unter denselben Bedingungen erneut alle drei Durchläufe ausgeführt werden. Ein einzelnes besseres Ergebnis darf den fehlgeschlagenen Datensatz nicht überschreiben.
Der eigentliche Nutzen einer Prüfung auf Energieregressionen besteht nicht darin, einen ansprechend wirkenden Wert zu erzeugen. Entscheidend ist, Testszenario, Gerätezustand, ursprüngliche Traces und Code-Commit miteinander zu verknüpfen. Nur wenn sich diese Nachweise reproduzierbar erfassen lassen, können Abweichungen eindeutig zugeordnet werden, und die Prüfung verkommt nicht zu einer Rauschquelle, die regelmäßig übersprungen wird.
Häufig gestellte Fragen
Kann der iOS-Simulator ein echtes Gerät bei Energiemessungen ersetzen?
Nein. Der Simulator eignet sich zur Prüfung von Skript und Szenario, die endgültige Energiebasis muss jedoch auf einem festen physischen Gerät mit fester Systemversion entstehen.
Soll eine einzelne Überschreitung den Merge blockieren?
Nein. Führen Sie mindestens drei Messungen aus, vergleichen Sie den Median und blockieren Sie erst bei einer wiederholten Abweichung mit auswertbarem Trace.
Den nächsten Build auf einen dedizierten physischen Knoten verschieben
Wählen Sie aus drei Apple-Silicon-Konfigurationen und sechs verfügbaren Knoten. Maßgeblich ist der in der Konsole in Echtzeit angezeigte Status.