Erste Schritte mit Spielschleifentests

Es kann schwierig sein, Spieletests zu automatisieren, wenn Gaming-Apps auf verschiedenen UI-Frameworks basieren. Mit Game Loop-Tests können Sie Ihre nativen Tests in Test Lab einbinden und ganz einfach auf ausgewählten Geräten ausführen. Bei einem Game Loop-Test wird Ihr Test durch Ihre Gaming-App ausgeführt und die Aktionen eines echten Spielers simuliert. In diesem Leitfaden erfahren Sie, wie Sie einen Game Loop-Test ausführen und die Testergebnisse dann in der Firebase-Konsole ansehen und verwalten.

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:

  • Spielen Sie ein Level Ihres Spiels so, wie es ein Endnutzer tun würde. Sie können die Eingabe des Nutzers entweder skripten, den Nutzer inaktiv lassen oder ihn durch eine KI ersetzen, wenn dies in Ihrem Spiel sinnvoll ist. Angenommen, Sie haben eine Rennwagen-Gaming-App und haben bereits eine KI implementiert. Sie können ganz einfach einen KI-basierten Fahrer für die Nutzereingabe verantwortlich machen.
  • Führen Sie Ihr Spiel mit der höchsten Qualitätseinstellung aus, um zu sehen, ob die Geräte diese unterstützen.
  • Einen technischen Test ausführen (z. B. mehrere Shader kompilieren, ausführen und prüfen, ob die Ausgabe wie erwartet ist)

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

Hinweis

Wenn Sie einen Test implementieren möchten, müssen Sie Ihre App zuerst für Game Loop-Tests konfigurieren.

  1. Fügen Sie Ihrer Aktivität im App-Manifest 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 mit einer bestimmten Absicht ausgelöst wird.

  2. Fügen Sie Ihrem Code (wir empfehlen innerhalb der onCreate-Methodendeklaration) Folgendes hinzu:

    Kotlin+KTX

    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, der sie auslöst. Sie können diesen Code auch später hinzufügen, z.B. nach dem ersten Laden der Game Engine.

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

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    Dadurch wird Ihre App geschlossen, wenn der Test der Spielschleife abgeschlossen ist. Der Test verwendet das UI-Framework Ihrer App, um den nächsten Loop zu starten. Wenn Sie die App schließen, wird der Test beendet.

Spielschleifentest erstellen und ausführen

Nachdem Sie Ihre App für Game Loop-Tests 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-Konsole oder die gcloud-Befehlszeile oder auf einem lokalen Gerät mit dem Test Loop Manager ausführen.

Auf einem lokalen Gerät ausführen

Der Test Loop Manager von Test Lab ist eine Open-Source-App, mit der Sie Spielschleifentests integrieren 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 mit dem Test Loop Manager einen Test auf einem lokalen Gerät aus:

  1. Laden Sie den Test Loop Manager auf ein Smartphone oder Tablet herunter und installieren Sie ihn mit dem Befehl:
    adb install testloopmanager.apk
  2. Öffnen Sie auf Ihrem Smartphone oder Tablet die App Test Loop Apps. Die App zeigt eine Liste der Apps auf Ihrem Gerät an, die mit Game Loops 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 Vorbereitung beschriebenen übereinstimmt.
  3. Wählen Sie die Gaming-App und dann die Anzahl der Wiederholungen aus, die Sie ausführen möchten. Hinweis: In diesem Schritt können Sie statt nur einer Schleife eine Teilmenge von Schleifen ausführen. Weitere Informationen zum Ausführen mehrerer Schleifen gleichzeitig finden Sie unter Optionale Funktionen.
  4. Klicken Sie auf Testen. Der Test wird sofort ausgeführt.

In Test Lab ausführen

Sie können einen Game Loop-Test in Test Lab entweder mit der Firebase Console oder der gcloud CLI ausführen. Öffnen Sie vor Beginn die Firebase-Konsole und erstellen Sie ein Projekt.

Firebase-Konsole verwenden

  1. Klicken Sie in der Firebase-Konsole im linken Bereich auf Test Lab.
  2. Klicken Sie auf Ersten Test ausführen oder auf Test ausführen, wenn für Ihr Projekt bereits ein Test ausgeführt wurde.
  3. Wählen Sie als Testtyp Game Loop aus und klicken Sie auf Weiter.
  4. Klicken Sie auf Durchsuchen und gehen Sie dann zur Datei .apk Ihrer App. Hinweis: In diesem Schritt können Sie statt einer Schleife eine Teilmenge von Schleifen ausführen. Weitere Informationen zum Ausführen mehrerer Schleifen gleichzeitig 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 Tests mit der Firebase Console starten.

gcloud-Befehlszeile verwenden

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

  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 steht PROJECT_ID für die ID Ihres Firebase-Projekts:

    gcloud config set project PROJECT_ID
    
  4. Ersten Test ausführen:

    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. Dazu gehören die Möglichkeit zum Schreiben von Ausgabedaten, die Unterstützung mehrerer Game Loops und Labels für zugehörige Loops.

Ausgabedaten schreiben

Der Game Loop-Test kann die Ausgabe in eine Datei schreiben, die in der Methode launchIntent.getData() angegeben ist. Nach einem Test können Sie auf diese Ausgabedaten im Bereich Test Lab der Firebase-Konsole zugreifen (siehe Beispiel für eine Game Loop-Testausgabedatei).

Test Lab folgt den Best Practices für die Freigabe von Dateien zwischen Apps, die unter Dateien freigeben beschrieben sind. In der onCreate()-Methode Ihrer Aktivität, in der sich Ihre Intent-Definition befindet, können Sie die Datenausgabedatei mit dem folgenden Code prüfen:

Kotlin+KTX

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 von der C++-Seite Ihrer Spiel-App in die Datei schreiben möchten, können Sie den Dateideskriptor anstelle des Dateipfads übergeben:

Kotlin+KTX

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

Mit Ausgabedatendateien (formatiert wie im Beispiel unten) können Sie Testergebnisse für den Game Loop im Bereich Test Lab der Firebase-Konsole anzeigen. Bereiche, die als /.../ angezeigt werden, können beliebige benutzerdefinierte Felder enthalten, solange sie nicht mit den Namen anderer Felder in dieser Datei in Konflikt stehen:

{
  "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 Game Loops

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

So aktivieren Sie in Ihrer App mehrere Schleifen gleichzeitig:

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

    1. Fügen Sie dem Manifest Ihrer App die folgende Zeile innerhalb des Elements <application> hinzu:

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

      Dieser Start-Intent enthält die Zielschleife als Ganzzahlparameter. Geben Sie im Feld android:value eine Ganzzahl zwischen 1 und 1.024 ein (die maximale Anzahl von Schleifen, die für einen einzelnen Test zulässig sind). Hinweis: Schleifen werden ab 1 und nicht ab 0 indexiert.

    2. In der Test Loop Manager App wird ein Auswahlbildschirm angezeigt, auf dem Sie auswählen können, welche Loops ausgeführt werden sollen. Wenn Sie mehrere Schleifen auswählen, wird jede Schleife nach Abschluss der vorherigen Schleife gestartet.

  • 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 Schleifenzahlen an. Beispiel: Mit --scenario-numbers=1,3,5 werden Schleifen 1, 3 und 5 ausgeführt.

  • Wenn Sie C++ verwenden und das Verhalten des Loops ändern möchten, übergeben Sie Ihrem nativen C++-Code Folgendes:

    Kotlin+KTX

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

    Java

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

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

Game Loops labeln

Wenn Sie Ihre Game Loops mit einem oder mehreren Szenariolabels versehen, können Sie und Ihr QA-Team ganz einfach eine Reihe ähnlicher Game Loops starten (z.B. „alle Kompatibilitäts-Gameloops“) und sie 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: For-Schleifen, mit denen die Interaktionen eines echten Nutzers beim Spielen des Spiels nachgestellt werden. Ziel dieser Tests ist es, Probleme zu finden, mit denen echte Nutzer beim Spielen des Spiels konfrontiert wären.
  • com.google.test.loops.gpu_compatibility: For-Schleifen, mit denen GPU-bezogene Probleme getestet werden. Ziel dieser Tests ist es, GPU-Code auszuführen, der in der Produktion möglicherweise nicht richtig ausgeführt wird, um Probleme mit Hardware und Treibern aufzudecken.
  • com.google.test.loops.compatibility: For-Schleifen, mit denen eine Vielzahl von Kompatibilitätsproblemen getestet werden kann, einschließlich E/A- und OpenSSL-Problemen.
  • com.google.test.loops.performance: For-Schleifen, mit denen die Leistung des Geräts getestet wird. So kann ein Spiel beispielsweise mit den komplexesten Grafikeinstellungen ausgeführt werden, um zu sehen, wie sich ein neues Gerät verhält.

So aktivieren Sie in Ihrer App Schleifen mit demselben Label:

  • 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 1.024 (die maximal zulässige Anzahl von Schleifen für einen einzelnen Test) angeben, die die Schleifen repräsentieren, die Sie beschriften möchten. Die Schleifen werden ab 1 und nicht ab 0 indexiert. Mit android:value="1,3-5" wird LABEL_NAME beispielsweise auf die Schleifen 1, 3, 4 und 5 angewendet.

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

  • Wenn Sie einen Test mit der Firebase-Konsole ausführen, geben Sie ein oder mehrere Labels in das Feld Labels ein.

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

Support für die App-Lizenzierung

Test Lab unterstützt Apps, die den von Google Play angebotenen Dienst zur App-Lizenzierung nutzen. Damit die Lizenzierung beim Testen Ihrer App mit Test Lab überprüft werden kann, müssen Sie Ihre App im Play Store im Produktionskanal veröffentlichen. Wenn Sie Ihre App mit Test Lab im Alpha- oder Betakanal testen möchten, entfernen Sie die Lizenzprüfung, bevor Sie Ihre App auf Test Lab hochladen.

Bekannte Probleme

Bei Spielschleifentests in Test Lab sind die folgenden bekannten Probleme zu beachten:

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