Inizia a utilizzare i test del ciclo di gioco

Può essere difficile automatizzare i test dei giochi quando le app di gioco sono basate su framework UI diversi. I test dei cicli di gioco ti consentono di integrare i test nativi con Test Lab ed eseguirli facilmente sui dispositivi che selezioni. Un test dei cicli di gioco esegue il tuo test nell'app di gioco simulando le azioni di un giocatore reale. Questa guida mostra come eseguire un test dei cicli di gioco, quindi visualizzare e gestire i risultati dei test nella Firebase console.

A seconda del motore di gioco, puoi implementare test con uno o più cicli. Un ciclo è un'esecuzione completa o parziale del test nell'app di gioco. I cicli di gioco possono essere utilizzati per:

  • Eseguire un livello del gioco nello stesso modo in cui lo farebbe un utente finale. Puoi scrivere lo script dell'input dell'utente, lasciare che l'utente sia inattivo o sostituire l' utente con un'AI se ha senso nel tuo gioco (ad es. se hai un'app di gioco di auto da corsa e hai già implementato un'AI. Puoi facilmente affidare a un pilota AI l'input dell'utente).
  • Eseguire il gioco con l'impostazione di qualità più elevata per verificare se i dispositivi la supportano.
  • Eseguire un test tecnico (compilare più shader, eseguirli, verificare che l' output sia quello previsto e così via).

Puoi eseguire un test dei cicli di gioco su un singolo dispositivo di test, su un insieme di dispositivi di test o su Test Lab. Tuttavia, non è consigliabile eseguire test dei cicli di gioco su dispositivi virtuali perché hanno frame rate grafici inferiori rispetto ai dispositivi fisici.

Prima di iniziare

Per implementare un test, devi prima configurare l'app per i test dei cicli di gioco.

  1. Nel file manifest dell'app, aggiungi un nuovo filtro per intent alla tua attività:

    <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>

    In questo modo, Test Lab può avviare il gioco attivandolo con un intent specifico.

  2. Nel codice (ti consigliamo di farlo all'interno della dichiarazione del metodo onCreate), aggiungi quanto segue:

    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
    }

    In questo modo, la tua attività può controllare l'intent che la avvia. Se preferisci, puoi aggiungere questo codice anche in un secondo momento (ad es. dopo aver caricato inizialmente il motore di gioco).

  3. Consigliato: alla fine del test, aggiungi:

    Kotlin

    yourActivity.finish()

    Java

    yourActivity.finish();

    In questo modo, l'app viene chiusa al termine del test dei cicli di gioco. Il test si basa su il framework UI dell'app per avviare il ciclo successivo e la chiusura dell'app indica che il test è terminato.

Creare ed eseguire un test dei cicli di gioco

Dopo aver configurato l'app per i test dei cicli di gioco, puoi creare immediatamente un test ed eseguirlo nell'app di gioco. Puoi scegliere di eseguire un test in Test Lab utilizzando la Firebase console o l'interfaccia a riga di comando (CLI) gcloud oppure su un dispositivo locale utilizzando Test Loop Manager.

Eseguire su un dispositivo locale

Test Lab's Test Loop Manager è un'app open source che ti aiuta a integrare i test dei cicli di gioco ed eseguirli sui tuoi dispositivi locali. Consente inoltre al team di controllo qualità di eseguire gli stessi cicli di gioco sui propri dispositivi.

Per eseguire un test su un dispositivo locale utilizzando Test Loop Manager:

  1. Scarica Test Loop Manager su uno smartphone o tablet e installalo eseguendo:
    adb install testloopmanager.apk
  2. Sul dispositivo, apri l'app Test Loop Apps sullo smartphone o sul tablet. L'app mostra un elenco di app sul dispositivo che possono essere eseguite con i cicli di gioco. Se non vedi la tua app di gioco, assicurati che il filtro per intent corrisponda a quello descritto nel primo passaggio della sezione Prima di iniziare.
  3. Seleziona l'app di gioco, quindi seleziona il numero di cicli che vuoi eseguire. Nota: in questo passaggio, puoi scegliere di eseguire un sottoinsieme di cicli anziché un solo ciclo. Per ulteriori informazioni sull' esecuzione di più cicli contemporaneamente, consulta Funzionalità facoltative.
  4. Fai clic su Esegui test. Il test inizia immediatamente.

Eseguire in Test Lab

Puoi eseguire un test dei cicli di gioco in Test Lab utilizzando la Firebase console o la gcloud CLI. Prima di iniziare, se non l'hai già fatto, apri la Firebase console e crea un progetto.

Utilizzare la console Firebase

  1. Nella Firebase console, fai clic su Test Lab nel riquadro a sinistra.
  2. Fai clic su Esegui il tuo primo test (o Esegui un test se il tuo progetto ha già eseguito un test).
  3. Seleziona Ciclo di gioco come tipo di test, quindi fai clic su Continua.
  4. Fai clic su Sfoglia, quindi vai al file .apk dell'app. Nota: in questo passaggio, puoi scegliere di eseguire un sottoinsieme di cicli anziché un solo ciclo. Per ulteriori informazioni sull' esecuzione di più cicli contemporaneamente, consulta Funzionalità facoltative.
  5. Fai clic su Continua.
  6. Seleziona i dispositivi fisici da utilizzare per testare l'app.
  7. Fai clic su Avvia test.

Per ulteriori informazioni su come iniziare a utilizzare la console Firebase, consulta Iniziare a eseguire test con la console Firebase.

Utilizzare la riga di comando (CLI) gcloud

  1. Se non l'hai già fatto, scarica e installa il Google Cloud SDK

  2. Accedi a gcloud CLI utilizzando il tuo Account Google:

    gcloud auth login

  3. Imposta il progetto Firebase in gcloud, dove PROJECT_ID è l'ID del tuo progetto Firebase:

    gcloud config set project PROJECT_ID
    
  4. Esegui il tuo primo test:

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

Per ulteriori informazioni su come iniziare a utilizzare gcloud CLI, consulta Iniziare a eseguire test dalla riga di comando gcloud.

Funzionalità facoltative

Test Lab offre diverse funzionalità facoltative che ti consentono di personalizzare ulteriormente i test, tra cui la possibilità di scrivere dati di output, il supporto per più cicli di gioco e le etichette per i cicli correlati.

Scrivere dati di output

Il test dei cicli di gioco può scrivere l'output in un file specificato nel launchIntent.getData() metodo. Dopo aver eseguito un test, puoi accedere a questi dati di output nella sezione Test Lab della console Firebase (vedi Esempio di file di output del test dei cicli di gioco).

Test Lab segue le best practice per la condivisione di un file tra le app descritte in Condividere un file. Nel metodo onCreate() della tua attività, in cui si trova l'intent, puoi controllare il file di output dei dati eseguendo il seguente codice:

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());
    // ...
}

Se vuoi scrivere nel file dal lato C++ dell'app di gioco, puoi passare il descrittore del file anziché il percorso del file:

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);
}

Esempio di file di output

Puoi utilizzare i file di dati di output (formattati come nell'esempio riportato di seguito) per visualizzare i risultati dei test dei cicli di gioco nella sezione Test Lab della console Firebase. Le aree mostrate come /.../ possono contenere tutti i campi personalizzati di cui hai bisogno, purché non siano in conflitto con i nomi di altri campi utilizzati in questo file:

{
  "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
}

Più cicli di gioco

Potrebbe essere utile eseguire più cicli di gioco nella tua app. Un ciclo è un esecuzione completa dell'app di gioco dall'inizio alla fine. Ad esempio, se il gioco ha più livelli, potresti voler avere un ciclo di gioco per avviare ogni livello anziché un ciclo che li scorre tutti. In questo modo, se l'app si arresta in modo anomalo al livello 32, puoi avviare direttamente quel ciclo di gioco per riprodurre l'arresto anomalo e testare le correzioni dei bug.

Per consentire all'app di eseguire più cicli contemporaneamente:

  • Se esegui un test con Test Loop Manager:

    1. Aggiungi la seguente riga al file manifest dell'app, all'interno dell'elemento <application>:

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

      Questo intent di avvio contiene il ciclo di destinazione come parametro intero. Nel campo android:value, puoi specificare un numero intero da 1 a 1024 (il numero massimo di cicli consentiti per un singolo test). Tieni presente che i cicli sono indicizzati a partire da 1, non da 0.

    2. Nell'app Test Loop Manager viene visualizzata una schermata di selezione che ti consente di selezionare i cicli che vuoi eseguire. Se selezioni più cicli, ogni ciclo viene avviato in sequenza al termine del ciclo precedente

  • Se esegui un test con la Firebase console, inserisci un elenco o un intervallo di numeri di ciclo nel campo Scenari.

  • Se esegui un test con gcloud CLI, specifica un elenco di numeri di ciclo utilizzando il flag --scenario-numbers. Ad esempio, --scenario-numbers=1,3,5 esegue i cicli 1, 3 e 5.

  • Se scrivi in C++ e vuoi modificare il comportamento del ciclo, passa il seguente extra al codice C++ nativo:

    Kotlin

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

    Java

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

    Ora puoi modificare il comportamento del ciclo in base al int valore risultante.

Etichettare i cicli di gioco

Quando etichetti i cicli di gioco con una o più etichette di scenario, tu e il tuo team di controllo qualità potete avviare facilmente un insieme di cicli di gioco correlati (ad es. "tutti i cicli di gioco di compatibilità game loops") e testarli in una singola matrice. Puoi creare etichette personalizzate o utilizzare le etichette predefinite offerte da Test Lab:

  • com.google.test.loops.player_experience: per i cicli utilizzati per riprodurre l'esperienza di un utente reale durante il gioco. L'obiettivo dei test con questi cicli è trovare problemi che un utente reale potrebbe riscontrare durante il gioco.
  • com.google.test.loops.gpu_compatibility: per i cicli utilizzati per testare i problemi relativi alla GPU. L'obiettivo dei test con questi cicli è eseguire codice GPU che potrebbe non essere eseguito correttamente in produzione, per esporre problemi con hardware e driver.
  • com.google.test.loops.compatibility: per i cicli utilizzati per testare un' ampia gamma di problemi di compatibilità, inclusi problemi di I/O e OpenSSL problemi.
  • com.google.test.loops.performance: per i cicli utilizzati per testare le prestazioni del dispositivo. Ad esempio, un gioco potrebbe essere eseguito con le impostazioni grafiche più complesse per vedere come si comporta un nuovo dispositivo.

Per consentire all'app di eseguire cicli con la stessa etichetta:

  • Se esegui un test con Test Loop Manager:

    1. Nel file manifest dell'app, aggiungi la seguente riga di metadati e sostituisci LABEL_NAME con un'etichetta a tua scelta:

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

      Nel campo android:value, puoi specificare un intervallo o un insieme di numeri interi da 1 a 1024 (il numero massimo di cicli consentiti per un singolo test) che rappresentano i cicli che vuoi etichettare. Tieni presente che i cicli sono indicizzati a partire da 1, non da 0. Ad esempio, android:value="1,3-5" applica LABEL_NAME ai cicli 1, 3, 4 e 5.

    2. Nell'app Test Loop Manager, inserisci una o più etichette nel campo Etichette.

  • Se esegui un test con la Firebase console, inserisci una o più etichette nel campo Etichette.

  • Se esegui un test con gcloud CLI, specifica una o più etichette di scenario utilizzando il --scenario-labels flag (ad es. --scenario-labels=performance,gpu).

Supporto per le licenze delle app

Test Lab supporta le app che utilizzano il servizio di gestione licenze delle app offerto da Google Play. Per controllare correttamente le licenze durante il test della tua app con Test Lab, devi pubblicare l'app nel canale di produzione nel Play Store. Per testare l'app nel canale alfa o beta utilizzando Test Lab, rimuovi il controllo delle licenze prima di caricare l'app in Test Lab.

Problemi noti

I test dei cicli di gioco in Test Lab presentano i seguenti problemi noti:

  • Alcuni arresti anomali non supportano le backtrace. Ad esempio, alcune build di release potrebbero sopprimere l'output del processo debuggerd utilizzando prctl(PR_SET_DUMPABLE, 0). Per saperne di più, consulta debuggerd.
  • Al momento, il livello API 19 non è supportato a causa di errori di autorizzazione dei file.