Può essere difficile automatizzare i test dei giochi quando le app di gioco sono basate su diversi framework UI. I test del ciclo di gioco consentono di integrare i test nativi con Test Lab ed eseguirli facilmente sui dispositivi selezionati. Un test di ciclo di gioco esegue il test tramite la tua app di gioco simulando le azioni di un giocatore reale. Questa guida ti mostra come eseguire un test Ciclo di gioco, quindi visualizzare e gestire i risultati del test nella console Firebase.
A seconda del motore di gioco, puoi implementare test con loop singoli o multipli. Un ciclo è un'esecuzione completa o parziale del test sulla tua app di gioco. I cicli di gioco possono essere utilizzati per:
- Esegui un livello del tuo gioco nello stesso modo in cui lo farebbe un utente finale. Puoi scrivere script per l'input dell'utente, lasciare che l'utente sia inattivo o sostituire l'utente con un'IA se ha senso nel tuo gioco (ad es. se hai un'app di giochi di corse e hai già implementato un'IA. Puoi facilmente affidare l'input dell'utente a un driver IA).
- Esegui il gioco con l'impostazione di qualità più alta per verificare se i dispositivi la supportano.
- Esegui un test tecnico (compila più shader, eseguili, controlla che l'output sia come previsto e così via).
Puoi eseguire un test Ciclo di gioco su un singolo dispositivo di test, su un insieme di dispositivi di test o su Test Lab. Tuttavia, sconsigliamo di eseguire i test del ciclo di gioco su dispositivi virtuali perché hanno frequenze fotogrammi grafiche inferiori rispetto ai dispositivi fisici.
Prima di iniziare
Per implementare un test, devi prima configurare l'app per i test Ciclo di gioco.
Nel manifest dell'app, aggiungi un nuovo filtro per intent all'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 tuo gioco attivandolo con un'intent specifica.
Nel codice (consigliamo all'interno della dichiarazione del metodo
onCreate
), aggiungi quanto segue: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 }
In questo modo, la tua attività può controllare l'intent che la avvia. Puoi anche aggiungere questo codice in un secondo momento (ad es. dopo aver caricato inizialmente il motore di gioco).
Consigliato: al termine del test, aggiungi:
Kotlin+KTX
yourActivity.finish()
Java
yourActivity.finish();
L'app viene chiusa al termine del test del ciclo di gioco. Il test si basa sul framework UI dell'app per avviare il ciclo successivo e la chiusura dell'app indica che il test è terminato.
Crea ed esegui un test Ciclo di gioco
Dopo aver configurato l'app per i test di Game Loop, puoi creare immediatamente un test e eseguirlo nella tua app di gioco. Puoi scegliere di eseguire un test in Test Lab utilizzando la console Firebase o la interfaccia a riga di comando (CLI) gcloud oppure su un dispositivo locale utilizzando Test Loop Manager.
Eseguire su un dispositivo locale
Test Loop Manager di Test Lab è un'app open source che ti aiuta a integrare i test di Game Loop ed eseguirli sui tuoi dispositivi locali. Inoltre, consente al tuo team di controllo qualità di eseguire gli stessi loop di gioco sui propri dispositivi.
Per eseguire un test su un dispositivo locale utilizzando Test Loop Manager:
- Scarica Test Loop Manager su uno smartphone o tablet e installalo eseguendo:
adb install testloopmanager.apk
- Sul tuo dispositivo, apri l'app App Test Loop sul tuo telefono o tablet. L'app mostra un elenco di app sul tuo dispositivo che possono essere eseguite con i cicli di gioco. Se qui non trovi la tua app di gioco, assicurati che il filtro per intent corrisponda a quello descritto nel primo passaggio della sezione Prima di iniziare.
- Seleziona la tua app di gioco, quindi seleziona il numero di loop che vuoi eseguire. Nota: in questo passaggio, puoi scegliere di eseguire un sottoinsieme di loop anziché solo un loop. Per ulteriori informazioni sull'esecuzione di più loop contemporaneamente, consulta la sezione Funzionalità facoltative.
- Fai clic su Esegui test. L'esecuzione del test inizia immediatamente.
Esegui in Test Lab
Puoi eseguire un test del ciclo di gioco in Test Lab utilizzando la console Firebase o la CLI gcloud. Prima di iniziare, se non l'hai già fatto, apri la console Firebase e crea un progetto.
Utilizzare la console Firebase
- Nella console Firebase, fai clic su Test Lab nel riquadro a sinistra.
- Fai clic su Esegui il tuo primo test (o Esegui un test se il progetto ha già eseguito un test).
- Seleziona Game Loop come tipo di test e poi fai clic su Continua.
- Fai clic su Sfoglia e vai al file
.apk
dell'app. Nota: in questo passaggio, puoi scegliere di eseguire un sottoinsieme di loop anziché solo un loop. Per ulteriori informazioni sull'esecuzione di più cicli contemporaneamente, consulta la sezione Funzionalità facoltative. - Fai clic su Continua.
- Seleziona i dispositivi fisici da utilizzare per testare l'app.
- Fai clic su Inizia test.
Per maggiori informazioni su come iniziare a utilizzare la console Firebase, consulta Avviare i test con la console Firebase.
Utilizza la riga di comando gcloud (CLI)
Se non l'hai ancora fatto, scarica e installa Google Cloud SDK.
Accedi a gcloud CLI utilizzando il tuo Account Google:
gcloud auth login
Imposta il tuo progetto Firebase in gcloud, dove
PROJECT_ID
è l'ID del tuo progetto Firebase:gcloud config set project PROJECT_ID
Esegui il primo test:
gcloud firebase test android run \ --type=game-loop --app=<var>path-to-apk</var> \ --device model=herolte,version=23
Per saperne di più su come iniziare a utilizzare la CLI gcloud, consulta Avvia i test dalla riga di comando gcloud.
Funzionalità facoltative
Test Lab offre diverse funzionalità facoltative che ti consentono di personalizzare ulteriormente i test, inclusa la possibilità di scrivere i dati di output, il supporto di più loop di gioco e le etichette per i loop correlati.
Scrivere i dati di output
Il test del ciclo di gioco può scrivere l'output in un file specificato nel metodo launchIntent.getData()
. 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 di Game Loop).
Test Lab segue le best practice per la condivisione di un file tra app descritte in
Condividere un file.
Nel metodo onCreate()
dell'attività, dove si trova l'intent, puoi
controllare il file di output dei dati eseguendo questo codice:
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()); // ... }
Se vuoi scrivere nel file dal lato C++ della tua app di gioco, puoi passare il descrittore del file anziché il percorso del file:
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); }
Esempio di file di output
Puoi utilizzare i file di dati di output (formattati come nell'esempio seguente) per visualizzare i risultati del test del loop di gioco nella sezione Test Lab della console Firebase.
Le aree mostrate come /.../
possono contenere tutti i campi personalizzati di cui hai bisogno, a condizione che non entrino 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 }
Diversi cicli di gioco
Potresti trovare utile eseguire più cicli di gioco nella tua app. Un ciclo è un walkthrough completo dell'app di gioco dall'inizio alla fine. Ad esempio, se il tuo gioco contiene più livelli, potresti voler avere un ciclo di gioco per lanciare ogni livello, invece di avere un ciclo che si ripete tutti. In questo modo, se l'app si arresta in modo anomalo al livello 32, puoi avviare direttamente il loop di gioco per riprodurre l'arresto anomalo e testare le correzioni dei bug.
Per consentire all'app di eseguire più loop contemporaneamente:
Se stai eseguendo un test con il Gestore di test Loop:
Aggiungi la seguente riga al manifest dell'app, all'interno dell'elemento
<application>
:<meta-data android:name="com.google.test.loops" android:value="5" />
Questo intent di lancio contiene il loop di destinazione come parametro intero. Nel campo
android:value
, puoi specificare un numero intero compreso tra 1 e 1024 (il numero massimo di loop consentito per un singolo test). Tieni presente che i loop vengono indicizzati a partire da 1, non da 0.Nell'app Test Loop Manager viene visualizzata una schermata di selezione che consente di selezionare i loop da eseguire. Se selezioni più loop, ogni loop viene avviato in sequenza dopo il completamento di quello precedente.
Se stai eseguendo un test con la console Firebase, inserisci un elenco o un intervallo di numeri di loop nel campo Scenari.
Se stai eseguendo un test con gcloud CLI, specifica un elenco di numeri di loop utilizzando il flag
--scenario-numbers
. Ad esempio,--scenario-numbers=1,3,5
esegue i loop 1, 3 e 5.Se stai scrivendo codice C++ e vuoi modificare il comportamento del ciclo, passa il seguente parametro aggiuntivo al codice C++ nativo:
Kotlin+KTX
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 valore
int
risultato.
Etichettare i cicli di gioco
Quando etichetti i loop di gioco con una o più etichette di scenario, tu e il tuo team di QA potete lanciare facilmente un insieme di loop di gioco correlati (ad es. "tutti i loop di gioco di compatibilità") e testarli in un'unica matrice. Puoi creare le tue etichette o utilizzare le etichette predefinite offerte da Test Lab:
com.google.test.loops.player_experience
: per i loop utilizzati per riprodurre l'esperienza di un utente reale durante il gioco. L'obiettivo dei test con questi loop è trovare i problemi che un utente reale potrebbe affrontare durante il gioco.com.google.test.loops.gpu_compatibility
: For loop utilizzati per testare i problemi relativi alla GPU. L'obiettivo del test con questi loop è eseguire il codice GPU che potrebbe non essere eseguito correttamente in produzione, per esporre problemi con hardware e driver.com.google.test.loops.compatibility
: per i loop utilizzati per testare un'ampia gamma di problemi di compatibilità, inclusi problemi di I/O e OpenSSL.com.google.test.loops.performance
: i loop For utilizzati per testare le prestazioni del dispositivo. Ad esempio, un gioco potrebbe essere eseguito con le impostazioni grafiche più complesse per vedere il comportamento del nuovo dispositivo.
Per consentire all'app di eseguire cicli con la stessa etichetta:
Se stai eseguendo un test con Test Loop Manager:
Nel file manifest dell'app, aggiungi la seguente riga di metadati e sostituisciLABEL_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 da etichettare. Tieni presente che i loop sono indicizzati a partire da 1, non da 0. Ad esempio,android:value="1,3-5"
applicaLABEL_NAME ai loop 1, 3, 4 e 5.Nell'app Test Loop Manager, inserisci una o più etichette nel campo Etichette.
Se stai eseguendo un test con la console Firebase, inserisci una o più etichette nel campo Etichette.
Se esegui un test con gcloud CLI, specifica una o più etichette dello scenario utilizzando il flag
--scenario-labels
(ad es.--scenario-labels=performance,gpu
).
Assistenza per le licenze delle app
Test Lab supporta le app che utilizzano il servizio di licenza per le app offerto da Google Play. Per verificare correttamente le licenze durante i test della tua app con Test Lab, devi pubblicare l'app nel canale di produzione nel Play Store. Per testare la tua app nel canale alpha o beta utilizzando Test Lab, rimuovi il controllo della licenza prima di caricarla su Test Lab.
Problemi noti
I test del ciclo di gioco in Test Lab presentano i seguenti problemi noti:
- Alcuni arresti anomali non supportano le tracce arretrate. Ad esempio, alcune build di release potrebbero
eliminare l'output del processo
debuggerd
utilizzandoprctl(PR_SET_DUMPABLE, 0)
. Per scoprire di più, consultadebuggerd
. - Il livello API 19 non è attualmente supportato a causa di errori di autorizzazione dei file.