Erste Schritte mit Spielschleifentests

Es kann schwierig sein, Spieletests zu automatisieren, wenn Gaming-Apps auf verschiedenen UI-Frameworks basieren. Mit Spielschleifentests können Sie Ihre nativen Tests in Test Lab einbinden und sie ganz einfach auf den von Ihnen ausgewählten Geräten ausführen. Bei einem Spielschleifentest wird Ihr Test in Ihrer Gaming-App ausgeführt, während die Aktionen eines echten Spielers simuliert werden. In diesem Leitfaden erfahren Sie, wie Sie einen Spielschleifentest ausführen und dann Ihre Test ergebnisse in der Firebase Console ansehen und verwalten.

Was ist ein Spielschleifentest?

Da Gaming-Apps auf verschiedenen UI-Frameworks und Engines gerendert werden, z. B. Unity, Unreal oder OpenGL/Vulkan C++-Code, können UI-Elemente nicht mit Standardautomatisierungstools untersucht oder mit ihnen interagiert werden. Mit einem Spielschleifentest können Sie Ihre nativen Engine-Tests in Test Lab Test Lab einbinden, indem Sie Ihr Spiel mit einem Intent starten, der eine bestimmte Szenarionummer enthält. Diese Szenarionummer fordert Ihre App auf, vordefinierte Logik, KI-Simulationen oder Leistungsprüfungen direkt in Ihrer Spiel-Engine auszuführen.

Nach dem Start interagiert Test Lab nicht weiter mit der UI Ihres Spiels. Stattdessen fungiert Test Lab als Testtransport und -umgebung: Es startet das spezifische Szenario, überwacht Abstürze und Zeitüberschreitungen und erfasst alle benutzerdefinierten Ergebnisprotokolle, wenn Ihre App die Schleife beendet hat.

Unterschiede zwischen Spielschleifen und Instrumentierungstests

  • Instrumentierungstests (z. B. Espresso oder UI Automator) verwenden externe Frameworks, um UI-Interaktionen zu steuern, auf Schaltflächen zu klicken und den Anwendungsstatus in der Android-View-Hierarchie außerhalb Ihrer App zu bestätigen.
  • Spielschleifentests delegieren die Testlogik an Ihre App. Ihre App führt ihre eigene interne Testschleife oder -simulation ohne externe UI-Interaktion aus, während Test Lab Ihr Szenario auslöst und die Testausgabe erfasst.

Beispiele

Angenommen, Sie möchten prüfen, ob Ihr Spiel auf verschiedenen physischen Geräten mindestens 60 Frames pro Sekunde beibehält. Sie können Szenario 1 in Ihrem Spielcode implementieren, um das visuell komplexeste Level zu laden und einen KI-Spieler oder ein automatisiertes Skript zwei Minuten lang spielen zu lassen.

Wenn Test Lab Szenario 1 auslöst, startet Ihr Spiel die KI-Wiedergabe, überwacht die Zeiten für das Rendern von Frames und die Arbeitsspeichernutzung, streamt diese Messwerte in eine benutzerdefinierte Ausgabeprotokolldatei (logFile) und ruft finish() auf, wenn der Vorgang abgeschlossen ist. Test Lab erfasst dann die Protokolldatei und stellt sie Ihnen in Cloud Storage und der Firebase Console zur Verfügung.

Anwendungsfälle

Je nach Game Engine können Sie Tests mit einer oder mehreren Schleifen implementieren. Eine Schleife ist ein vollständiger oder teilweiser Durchlauf Ihres Tests in Ihrer Gaming-App. Spielschleifen können für Folgendes verwendet werden:

  • Ein Level Ihres Spiels so ausführen, wie es ein Endnutzer spielen würde. Sie können die Eingabe des Nutzers entweder skripten, den Nutzer inaktiv lassen oder den Nutzer durch eine KI ersetzen, wenn das in Ihrem Spiel sinnvoll ist. Wenn Sie beispielsweise eine Gaming-App für Rennwagen haben und bereits eine KI implementiert haben, können Sie einen KI-Fahrer mit der Eingabe des Nutzers beauftragen.
  • Ihr Spiel mit der höchsten Qualitätseinstellung ausführen, um zu prüfen, ob es von den Geräten unterstützt wird.
  • Einen technischen Test ausführen (mehrere Shader kompilieren, ausführen, prüfen, ob die Ausgabe wie erwartet ist usw.).

Sie können einen Spielschleifentest auf einem einzelnen Testgerät, einer Reihe von Testgeräten oder auf Test Lab ausführen. Wir empfehlen jedoch nicht, Spielschleifentests auf virtuellen Geräten auszuführen, da sie niedrigere Grafik-Framerate als physische Geräte haben.

Hinweis

Um einen Test zu implementieren, müssen Sie zuerst Ihre App für Spielschleifentests konfigurieren.

  1. Fügen Sie in Ihrem App-Manifest Ihrer Aktivität einen neuen Intent-Filter hinzu:

    <activity android:name=".MyActivity">
       <intent-filter>
           <action android:name="com.google.intent.action.TEST_LOOP"/>
           <category android:name="android.intent.category.DEFAULT"/>
           <data android:mimeType="application/javascript"/>
       </intent-filter>
       <intent-filter>
          ... (other intent filters here)
       </intent-filter>
    </activity>

    So kann Test Lab Ihr Spiel starten, indem es es mit einem bestimmten Intent auslöst.

  2. Fügen Sie in Ihrem Code (wir empfehlen in der Deklaration der Methode onCreate) Folgendes hinzu:

    Kotlin

    val launchIntent = intent
    if (launchIntent.action == "com.google.intent.action.TEST_LOOP") {
        val scenario = launchIntent.getIntExtra("scenario", 0)
        // Code to handle your game loop here
    }

    Java

    Intent launchIntent = getIntent();
    if(launchIntent.getAction().equals("com.google.intent.action.TEST_LOOP")) {
        int scenario = launchIntent.getIntExtra("scenario", 0);
        // Code to handle your game loop here
    }

    So kann Ihre Aktivität den Intent prüfen, mit dem sie gestartet wird. Sie können diesen Code auch später hinzufügen, wenn Sie möchten (z.B. nach dem ersten Laden Ihrer Game Engine).

  3. Empfohlen: Fügen Sie am Ende des Tests Folgendes hinzu:

    Kotlin

    yourActivity.finish()

    Java

    yourActivity.finish();

    Dadurch wird Ihre App geschlossen, wenn der Spielschleifentest abgeschlossen ist. Der Test verwendet das UI-Framework Ihrer App, um die nächste Schleife zu starten. Wenn Sie Ihre App schließen, wird dem Framework mitgeteilt, dass der Test beendet ist.

Spielschleifentest erstellen und ausführen

Nachdem Sie Ihre App für Spielschleifentests konfiguriert haben, können Sie sofort einen Test erstellen und in Ihrer Gaming-App ausführen. Sie können einen Test in Test Lab entweder über die Firebase Console oder die gcloud Befehlszeilenschnittstelle (Command Line Interface, CLI) oder auf einem lokalen Gerät mit dem Test Loop Manager ausführen.

Auf einem lokalen Gerät ausführen

Test LabDer Test Loop Manager von' ist eine Open-Source-App, mit der Sie Spielschleifentests einbinden und auf Ihren lokalen Geräten ausführen können. Außerdem kann Ihr Qualitätssicherungsteam dieselben Spielschleifen auf seinen Geräten ausführen.

So führen Sie einen Test auf einem lokalen Gerät mit dem Test Loop Manager aus:

  1. Laden Sie den Test Loop Manager auf ein Smartphone oder Tablet herunter und installieren Sie ihn, indem Sie Folgendes ausführen:
    adb install testloopmanager.apk
  2. Öffnen Sie auf Ihrem Gerät die App Test Loop Apps auf Ihrem Smartphone oder Tablet. In der App wird eine Liste der Apps auf Ihrem Gerät angezeigt, die mit Spielschleifen ausgeführt werden können. Wenn Ihre Gaming-App hier nicht angezeigt wird, prüfen Sie, ob Ihr Intent-Filter mit dem im ersten Schritt des Abschnitts „Hinweis“ beschriebenen übereinstimmt.
  3. Wählen Sie Ihre Gaming-App und dann die Anzahl der Schleifen aus, die Sie ausführen möchten. Hinweis: In diesem Schritt können Sie anstelle einer einzelnen Schleife auch eine Teilmenge von Schleifen ausführen. Weitere Informationen zum gleichzeitigen Ausführen mehrerer Schleifen finden Sie unter Optionale Funktionen.
  4. Klicken Sie auf Test ausführen. Der Test wird sofort ausgeführt.

In Test Lab ausführen

Sie können einen Spielschleifentest in Test Lab entweder über die Firebase Konsole oder die gcloud CLI ausführen. Öffnen Sie zuerst die Firebase Konsole und erstellen Sie ein Projekt, falls Sie das noch nicht getan haben, bevor Sie beginnen.

Firebase Console verwenden

  1. Klicken Sie in der Firebase Console im linken Steuerfeld auf Test Lab.
  2. Klicken Sie auf Ersten Test ausführen oder auf Test ausführen , wenn in Ihrem Projekt bereits ein Test ausgeführt wurde.
  3. Wählen Sie als Testtyp Spielschleife aus und klicken Sie dann auf Weiter.
  4. Klicken Sie auf Durchsuchen und suchen Sie die .apk-Datei Ihrer App. Hinweis: In diesem Schritt können Sie anstelle einer einzelnen Schleife auch eine Teilmenge von Schleifen ausführen. Weitere Informationen zum gleichzeitigen Ausführen mehrerer Schleifen finden Sie unter Optionale Funktionen.
  5. Klicken Sie auf Weiter.
  6. Wählen Sie die physischen Geräte aus, mit denen Sie Ihre App testen möchten.
  7. Klicken Sie auf Tests starten.

Weitere Informationen zu den ersten Schritten mit der Firebase Console finden Sie unter Mit der Firebase Console testen.

gcloud-Befehlszeile (CLI) verwenden

  1. Laden Sie das Google Cloud SDK herunter und installieren Sie es, falls Sie das noch nicht getan haben.

  2. Melden Sie sich mit Ihrem Google-Konto in der gcloud CLI an:

    gcloud auth login

  3. Legen Sie Ihr Firebase-Projekt in gcloud fest. Dabei ist PROJECT_ID die ID Ihres Firebase-Projekts:

    gcloud config set project PROJECT_ID
    
  4. Führen Sie Ihren ersten Test aus:

    gcloud firebase test android run \
     --type=game-loop --app=<var>path-to-apk</var> \
     --device model=herolte,version=23
    

Weitere Informationen zu den ersten Schritten mit der gcloud CLI finden Sie unter Tests über die gcloud-Befehlszeile starten.

Optionale Funktionen

Test Lab bietet mehrere optionale Funktionen, mit denen Sie Ihre Tests weiter anpassen können, z. B. die Möglichkeit, Ausgabedaten zu schreiben, Unterstützung für mehrere Spiel schleifen und Labels für zugehörige Schleifen.

Ausgabedaten schreiben

Wenn Test Lab Ihr Spiel startet, wird eine URL angegeben, die auf eine lokale Ergebnisdatei auf dem Testgerät verweist. Sie ist mit launchIntent.getData() zugänglich. Ihr Spiel kann während des Testlaufs Testergebnisse, Leistungsmesswerte und Protokolle (logFile) direkt an diesen Speicherort schreiben.

Sie können beliebige Inhalte in die logFile schreiben, z. B. Nur-Text, CSV-Daten, Zeiten für das Rendern von Frames oder benutzerdefinierte Diagnoseberichte. Für die Inhalte, die Sie schreiben, gibt es keine Einschränkungen oder Formatierungsanforderungen. Die Datei wird erfasst, wenn der Test beendet ist, und zusammen mit Ihren anderen Testartefakten in Ihren Cloud Storage-Bucket hochgeladen.

Test Lab folgt den etablierten Best Practices für die Freigabe einer Datei zwischen Apps die unter Datei freigeben beschrieben sind. In der Methode onCreate() Ihrer Aktivität, in der sich Ihr Intent befindet, können Sie Ihre Datenausgabedatei abrufen und prüfen, indem Sie den folgenden Code ausführen:

Kotlin

val launchIntent = intent
val logFile = launchIntent.data
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    // ...
}

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    // ...
}

Wenn Sie aus der C++-Seite Ihrer Gaming-App in die Datei schreiben möchten, können Sie anstelle des Dateipfads den Dateideskriptor übergeben:

Kotlin

val launchIntent = intent
val logFile = launchIntent.data
var fd = -1
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    fd = try {
        contentResolver
            .openAssetFileDescriptor(logFile, "w")!!
            .parcelFileDescriptor
            .fd
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
        -1
    } catch (e: NullPointerException) {
        e.printStackTrace()
        -1
    }
}

// C++ code invoked here.
// native_function(fd);

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
int fd = -1;
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    try {
        fd = getContentResolver()
                .openAssetFileDescriptor(logFile, "w")
                .getParcelFileDescriptor()
                .getFd();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fd = -1;
    } catch (NullPointerException e) {
        e.printStackTrace();
        fd = -1;
    }
}

// C++ code invoked here.
// native_function(fd);

C++

#include <unistd.h>
JNIEXPORT void JNICALL
Java_my_package_name_MyActivity_native_function(JNIEnv *env, jclass type, jint log_file_descriptor) {
// The file descriptor needs to be duplicated.
int my_file_descriptor = dup(log_file_descriptor);
}

Beispiel für eine Ausgabedatei

Test Lab erfordert zwar kein bestimmtes Format für Ihre logFile, aber wenn Sie Ihre Ausgabe als JSON strukturieren, das dem folgenden Schema entspricht, kann die Firebase Console (https://console.firebase.google.com/project/_/testlab) Zusammenfassung messwerte für Ihren Spielschleifentest parsen und anzeigen.

Wichtige Details zu diesem Beispiel :

  • Wer stellt die Daten zur Verfügung? Sie (der Testentwickler) sind dafür verantwortlich, alle Messwerte aus Ihrem Spielcode zu berechnen und in diese Datei zu schreiben. Test Lab erfasst oder generiert diese Datenpunkte nicht automatisch für Sie.
  • Benutzerdefinierte Felder hinzufügen: Bereiche, die mit /.../ gekennzeichnet sind, geben an, wo Sie beliebige benutzerdefinierte Schlüssel-Wert-Paare hinzufügen können (z. B. "rendered_vertices": 12000 oder "ai_error_count": 0). Sie können Ihrer Ausgabe beim Schreiben der Datei aus Ihrer App eine beliebige gültige JSON-Property hinzufügen, solange die Feldnamen nicht mit Schemaspalten wie name oder start_timestamp in Konflikt stehen.
  • Wo finde ich die Ausgabedatei? Nach Abschluss des Tests wird die Rohausgabedatei im Ergebnisse-Bucket (GCS) Ihres Projekts im Artefaktverzeichnis des Testlaufs gespeichert und kann heruntergeladen werden. Sie können die geparste Ausgabe auch auf der Test Lab Seite der Firebase Console ansehen und prüfen.

Hier sehen Sie ein Beispiel für eine strukturierte JSON-Ausgabedatei:

{
  "name": "test name",
  "start_timestamp": 0, // Timestamp of the test start (in us).
                           Can be absolute or relative
  "driver_info": "...",
  "frame_stats": [
    {
      "timestamp": 1200000, // Timestamp at which this section was written
                               It contains value regarding the period
                               start_timestamp(0) -> this timestamp (1200000 us)
      "avg_frame_time": 15320, // Average time to render a frame in ns
      "nb_swap": 52, // Number of frame rendered
      "threads": [
        {
          "name": "physics",
          "Avg_time": 8030 // Average time spent in this thread per frame in us
        },
        {
          "name": "AI",
          "Avg_time": 2030 // Average time spent in this thread per frame in us
        }
      ],
      /.../ // Any custom field you want (vertices display on the screen, nb units …)
    },
    {
      // Next frame data here, same format as above
    }
  ],
  "loading_stats": [
    {
      "name": "assets_level_1",
      "total_time": 7850, // in us
      /.../
    },
    {
      "name": "victory_screen",
      "total_time": 554, // in us
      /.../
    }

  ],
  /.../, // You can add custom fields here
}

Mehrere Spielschleifen

Es kann nützlich sein, mehrere Spielschleifen in Ihrer App auszuführen. Eine Schleife ist ein vollständiger Durchlauf Ihrer Gaming-App von Anfang bis Ende. Wenn Ihr Spiel beispielsweise mehrere Level hat, können Sie für jedes Level eine Spielschleife verwenden, anstatt eine Schleife zu haben, die alle durchläuft. Wenn Ihre App auf Level 32 abstürzt, können Sie diese Spielschleife direkt starten, um den Absturz zu reproduzieren und Fehlerkorrekturen zu testen.

So aktivieren Sie die Ausführung mehrerer Schleifen gleichzeitig in Ihrer App:

  • Wenn Sie einen Test mit dem Test Loop Manager ausführen:

    1. Fügen Sie dem Manifest Ihrer App im Element <application> die folgende Zeile hinzu:

      <meta-data
        android:name="com.google.test.loops"
        android:value="5" />

      Dieser Start-Intent enthält die Zielschleife als Ganzzahlparameter. Im Feld android:value können Sie eine Ganzzahl von 1 bis 1024 angeben. Das ist die maximale Anzahl von Schleifen, die für einen einzelnen Test zulässig sind. Beachten Sie, dass Schleifen ab 1 und nicht ab 0 indexiert werden.

    2. In der App „Test Loop Manager“ wird ein Auswahlbildschirm angezeigt, auf dem Sie die auszuführenden Schleifen auswählen können. Wenn Sie mehrere Schleifen auswählen, wird jede Schleife nacheinander gestartet, nachdem die vorherige Schleife abgeschlossen ist.

  • Wenn Sie einen Test mit der Firebase Konsole ausführen, geben Sie im Feld Szenarien eine Liste oder einen Bereich von Schleifennummern ein.

  • Wenn Sie einen Test mit der gcloud CLI ausführen, geben Sie mit dem Flag --scenario-numbers eine Liste von Schleifennummern an. Beispiel: --scenario-numbers=1,3,5 führt die Schleifen 1, 3 und 5 aus.

  • Wenn Sie C++ schreiben und das Verhalten Ihrer Schleife ändern möchten, übergeben Sie Folgendes zusätzlich an Ihren nativen C++-Code:

    Kotlin

    val launchIntent = intent
    val scenario = launchIntent.getIntExtra("scenario", 0)

    Java

    Intent launchIntent = getIntent();
    int scenario = launchIntent.getIntExtra("scenario", 0);

    Sie können das Verhalten Ihrer Schleife jetzt basierend auf dem resultierenden int-Wert ändern.

Spielschleifen labeln

Wenn Sie Ihre Spielschleifen mit einem oder mehreren Szenariolabels versehen, können Sie und Ihr Qualitätssicherungsteam ganz einfach eine Reihe zugehöriger Spielschleifen (z.B. „alle Kompatibilitäts-Spielschleifen“) starten und in einer einzigen Matrix testen. Sie können eigene Labels erstellen oder die vordefinierten Labels von Test Lab verwenden:

  • com.google.test.loops.player_experience: Für Schleifen, die verwendet werden, um die Erfahrung eines echten Nutzers beim Spielen des Spiels zu reproduzieren. Ziel des Tests mit diesen Schleifen ist es, Probleme zu finden, die ein echter Nutzer beim Spielen des Spiels haben würde.
  • com.google.test.loops.gpu_compatibility: Für Schleifen, die verwendet werden, um GPU-bezogene Probleme zu testen. Ziel des Tests mit diesen Schleifen ist es, GPU-Code auszuführen, der in der Produktion möglicherweise nicht ordnungsgemäß ausgeführt wird, um Probleme mit Hardware und Treibern aufzudecken.
  • com.google.test.loops.compatibility: Für Schleifen, die verwendet werden, um eine breite Palette von Kompatibilitätsproblemen zu testen, einschließlich I/O- und OpenSSL-Problemen.
  • com.google.test.loops.performance: Für Schleifen, die verwendet werden, um die Leistung des Geräts zu testen. Beispielsweise kann ein Spiel mit den komplexesten Grafikeinstellungen ausgeführt werden, um zu sehen, wie sich ein neues Gerät verhält.

So aktivieren Sie die Ausführung von Schleifen mit demselben Label in Ihrer App:

  • Wenn Sie einen Test mit dem Test Loop Manager ausführen:

    1. Fügen Sie dem Manifest Ihrer App die folgende Metadatenzeile hinzu und ersetzen Sie LABEL_NAME durch ein Label Ihrer Wahl:

      <meta-data
       android:name="com.google.test.loops.LABEL_NAME"
       android:value="1,3-5" />

      Im Feld android:value können Sie einen Bereich oder eine Reihe von Ganzzahlen von 1 bis 1024 angeben. Das ist die maximale Anzahl von Schleifen, die für einen einzelnen Test zulässig sind. Diese Zahlen stellen die Schleifen dar, die Sie labeln möchten. Beachten Sie, dass Schleifen ab 1 und nicht ab 0 indexiert werden. Beispiel: android:value="1,3-5" wendet LABEL_NAME auf die Schleifen 1, 3, 4 und 5 an.

    2. Geben Sie in der App „Test Loop Manager“ im Feld Labels ein oder mehrere Labels ein.

  • Wenn Sie einen Test mit der Firebase Console ausführen, geben Sie im Feld Labels ein oder mehrere Labels ein.

  • Wenn Sie einen Test mit der gcloud CLI ausführen, geben Sie mit dem --scenario-labels Flag ein oder mehrere Szenariolabels an (z.B. --scenario-labels=performance,gpu).

Unterstützung für die App-Lizenzierung

Test Lab unterstützt Apps, die den von Google Play angebotenen App-Lizenzierungsservice verwenden. Wenn Sie die Lizenzierung beim Testen Ihrer App mit Test Lab prüfen möchten, müssen Sie Ihre App im Play Store im Produktionskanal veröffentlichen. Wenn Sie Ihre App im Alpha- oder Betakanal mit Test Lab testen möchten, entfernen Sie die Lizenzierungsprüfung, bevor Sie Ihre App in Test Lab hochladen.

Bekannte Probleme

Bei Spielschleifentests in Test Lab sind die folgenden Probleme bekannt:

  • Einige Abstürze unterstützen keine Backtraces. Bei einigen Release-Builds kann beispielsweise die Ausgabe des debuggerd-Prozesses mit prctl(PR_SET_DUMPABLE, 0) unterdrückt werden. Weitere Informationen finden Sie unter debuggerd.
  • API-Level 19 wird derzeit aufgrund von Fehlern bei den Dateiberechtigungen nicht unterstützt.