Inizia a utilizzare i test del ciclo di gioco per iOS

Con i test Ciclo di gioco, puoi scrivere test nativi per il motore grafico ed eseguirli in Test Lab sui dispositivi che scegli. In questo modo, non devi preoccuparti di scrivere per diversi framework di UI o di test. Un test Ciclo di gioco simula le azioni di un giocatore reale e, quando lo esegui in Test Lab, fornisce un modo rapido e scalabile per verificare che il gioco funzioni correttamente per gli utenti.

Questa pagina mostra come eseguire un test Ciclo di gioco, quindi visualizzare e gestire i risultati dei test nella pagina Test Lab della console Firebase. Puoi anche personalizzare ulteriormente i test con funzionalità facoltative, ad esempio scrivere risultati di test personalizzati o terminare il test in anticipo.

Che cos'è un test Ciclo di gioco?

Un ciclo è un'esecuzione completa o parziale del test sull'app di gioco. Puoi eseguire un test Ciclo di gioco localmente su un simulatore o su un insieme di dispositivi in Test Lab. I test Ciclo di gioco possono essere utilizzati per:

  • Eseguire il gioco come se fosse un utente finale. Puoi scrivere lo script dell'input dell'utente, lasciare che l'utente sia inattivo o sostituire l'utente con un'AI (ad esempio, se hai implementato l'AI in un gioco di corse automobilistiche, puoi incaricare un pilota AI dell'input dell'utente).

  • Eseguire il gioco con l'impostazione di qualità più elevata per scoprire quali dispositivi possono supportarlo.

  • Eseguire un test tecnico, ad esempio compilare più shader, eseguirli e verificare che l'output sia quello previsto.

Passaggio 1: registra lo schema URL personalizzato di Test Lab

Innanzitutto, devi registrare lo schema URL personalizzato di Firebase Test Lab's nella tua app:

  1. In Xcode, seleziona un target di progetto.

  2. Fai clic sulla scheda Info, quindi aggiungi un nuovo tipo di URL.

  3. Nel campo Schemi URL, inserisci firebase-game-loop. Puoi anche registrare lo schema URL personalizzato aggiungendolo al file di configurazione Info.plist del progetto in qualsiasi punto all'interno del tag <dict>:

    <key>CFBundleURLTypes</key>
     <array>
         <dict>
             <key>CFBundleURLName</key>
             <string></string>
             <key>CFBundleTypeRole</key>
             <string>Editor</string>
             <key>CFBundleURLSchemes</key>
             <array>
                 <string>firebase-game-loop</string>
             </array>
         </dict>
     </array>
    

L'app è ora configurata per eseguire un test utilizzando Test Lab.

Passaggio 2 (facoltativo): configura l'app per eseguire più cicli

Se la tua app ha più schemi URL personalizzati registrati e prevedi di eseguire più cicli (ovvero scenari) nel test, devi specificare quali cicli vuoi eseguire nell'app al momento dell'avvio.

Nell'app delegate, esegui l'override del metodo application(_:open:options:):

Swift

func application(_app: UIApplication,
                 open url: URL
                 options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
    if components.scheme == "firebase-game-loop" {
        // ...Enter Game Loop Test logic to override application(_:open:options:).
    }
    return true
}

Objective-C

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary &lt;UIApplicationOpenURLOptionsKey, id&gt; *)options {
  if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
      // ...Enter Game Loop Test logic to override application(_:open:options:).
  }
}

Quando esegui più cicli nel test, il ciclo corrente viene passato come parametro all'URL utilizzato per avviare l'app. Puoi anche ottenere il numero del ciclo corrente analizzando l'oggetto URLComponents utilizzato per recuperare lo schema URL personalizzato:

Swift

if components.scheme == "firebase-game-loop" {
    // Iterate over all parameters and find the one with the key "scenario".
    let scenarioNum = Int(components.queryItems!.first(where: { $0.name == "scenario" })!.value!)!
    // ...Write logic specific to the current loop (scenarioNum).
}

Objective-C

if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
    // Launch the app as part of a game loop.
    NSURLComponents *components = [NSURLComponents componentsWithURL:url
                                             resolvingAgainstBaseURL:YES];
    for (NSURLQueryItem *item in [components queryItems]) {
        if ([item.name isEqualToString:@"scenario"]) {
            NSInteger scenarioNum = [item.value integerValue];
            // ...Write logic specific to the current loop (scenarioNum).
        }
    }
}

Passaggio 3: crea ed esegui un test

Dopo aver registrato lo schema URL personalizzato di Test Lab, puoi eseguire il test nella console Firebase o con gcloud CLI beta. Se non l'hai ancora fatto, genera un file IPA per l'app (dovrai individuarlo in un secondo momento).

Esegui un test nella console Firebase

  1. Nella console Firebase, vai a DevOps e coinvolgimento > Test Lab.

  2. Fai clic su Esegui il primo test > Esegui un ciclo di gioco iOS.

  3. Nella sezione Carica app, fai clic su Sfoglia, quindi seleziona il file IPA dell'app (se non l'hai ancora fatto, genera un file IPA per l'app).

  4. (Facoltativo) Se vuoi eseguire più cicli (ovvero scenari) contemporaneamente o selezionare cicli specifici da eseguire, inserisci i numeri dei cicli nel campo Scenari.

    Ad esempio, quando inserisci 1-3, 5, Test Lab esegue i cicli 1, 2, 3, e 5. Per impostazione predefinita (se non inserisci nulla nel campo Scenari), Test Lab esegue solo il ciclo 1.

  5. Nella sezione Dispositivi, seleziona uno o più dispositivi fisici su cui vuoi testare l'app, quindi fai clic su Avvia test.

Esegui un test con gcloud CLI beta

  1. Se non l'hai ancora fatto, configura l'ambiente gcloud SDK locale, quindi assicurati di installare il componente gcloud beta.

  2. Esegui il comando gcloud beta firebase test ios run e utilizza i seguenti flag per configurare l'esecuzione:

Flag per i test Ciclo di gioco
--type

Obbligatorio: specifica il tipo di test iOS che vuoi eseguire. Puoi inserire tipi di test xctest (impostazione predefinita) o game-loop.

--app

Obbligatorio: percorso assoluto (Google Cloud Storage o file system) del file IPA dell'app. Questo flag è valido solo quando si eseguono test Ciclo di gioco.

--scenario-numbers

I cicli (ovvero gli scenari) che vuoi eseguire nella tua app. Puoi inserire un ciclo, un elenco di cicli o un intervallo di cicli. Il ciclo predefinito è 1.

Ad esempio, --scenario-numbers=1-3,5 esegue i cicli 1, 2, 3 e 5.

--device-model

Il dispositivo fisico su cui vuoi eseguire il test (scopri quali dispositivi disponibili puoi utilizzare).

--timeout

La durata massima per cui vuoi eseguire il test. Puoi inserire un numero intero per rappresentare la durata in secondi oppure un numero intero e un'enumerazione per rappresentare la durata come un'unità di tempo più lunga.

Ad esempio:

  • --timeout=200 forza la terminazione del test quando raggiunge i 200 secondi.
  • --timeout=1h forza la terminazione del test quando raggiunge un'ora.

Ad esempio, il seguente comando esegue un test Ciclo di gioco che esegue i cicli 1, 4, 6, 7 e 8 su un iPhone 8 Plus:

gcloud beta firebase test ios run
 --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8
 --device-model=iphone8plus

Per saperne di più su gcloud CLI, consulta la documentazione di riferimento.

Esegui un test localmente

Per eseguire il test localmente, carica l'app di gioco in un simulatore ed esegui:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • Puoi trovare l'UDID del simulatore eseguendo il comando instruments -s devices.

  • Se è in esecuzione un solo simulatore, inserisci la stringa speciale "booted" al posto di SIMULATOR_UDID.

Se il test contiene più cicli, puoi specificare il ciclo che vuoi eseguire passando il numero del ciclo al flag scenario. Tieni presente che puoi eseguire un solo ciclo alla volta quando esegui il test localmente. Ad esempio, se vuoi eseguire i cicli 1, 2 e 5, devi eseguire un comando separato per ogni ciclo:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=1
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5

Termina un test in anticipo

Per impostazione predefinita, un test Ciclo di gioco continua a essere eseguito fino a raggiungere un timeout di cinque minuti, anche quando tutti i cicli sono stati eseguiti. Quando viene raggiunto il timeout, il test termina e annulla tutti i cicli in attesa. Puoi velocizzare il test o terminarlo in anticipo chiamando lo schema URL personalizzato di Test Lab firebase-game-loop-complete nell'AppDelegate dell'app. Ad esempio:

Swift

/// End the loop by calling our custom url scheme.
func finishLoop() {
    let url = URL(string: "firebase-game-loop-complete://")!
    UIApplication.shared.open(url)
}

Objective-C

- (void)finishLoop {
  UIApplication *app = [UIApplication sharedApplication];
  [app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
      options:@{}
completionHandler:^(BOOL success) {}];
}

Il test Ciclo di gioco termina il ciclo corrente ed esegue il ciclo successivo. Quando non ci sono altri cicli da eseguire, il test termina.

Scrivi risultati di test personalizzati

Puoi configurare il test Ciclo di gioco in modo che scriva risultati di test personalizzati nel file system del dispositivo. In questo modo, quando il test inizia a essere eseguito, Test Lab archivia i file dei risultati in una directory GameLoopsResults sul dispositivo di test (che devi creare tu). Al termine del test, Test Lab sposta tutti i file dalla directory GameLoopResults al bucket del progetto. Tieni presente quanto segue quando configuri il test:

  • Tutti i file dei risultati vengono caricati indipendentemente dal tipo, dalle dimensioni o dalla quantità.

  • Test Lab non elabora i risultati dei test finché non sono stati eseguiti tutti i cicli del test, quindi se il test include più cicli che scrivono l'output, assicurati di aggiungerli a un file di risultati univoco o di creare un file di risultati per ogni ciclo. In questo modo, puoi evitare di sovrascrivere i risultati di un ciclo precedente.

Per configurare il test in modo che scriva risultati di test personalizzati:

  1. Nella directory Documents dell'app, crea una directory denominata GameLoopResults.

  2. Da qualsiasi punto del codice dell'app (ad es. l'app delegate), aggiungi quanto segue:

    Swift

    /// Write to a results file.
    func writeResults() {
      let text = "Greetings from game loops!"
      let fileName = "results.txt"
      let fileManager = FileManager.default
      do {
    
      let docs = try fileManager.url(for: .documentDirectory,
                                     in: .userDomainMask,
                                     appropriateFor: nil,
                                     create: true)
      let resultsDir = docs.appendingPathComponent("GameLoopResults")
      try fileManager.createDirectory(
          at: resultsDir,
          withIntermediateDirectories: true,
          attributes: nil)
      let fileURL = resultsDir.appendingPathComponent(fileName)
      try text.write(to: fileURL, atomically: false, encoding: .utf8)
      } catch {
        // ...Handle error writing to file.
      }
    }
    

    Objective-C

    /// Write to a results file.
    - (void)writeResults:(NSString *)message {
        // Locate and create the results directory (if it doesn't exist already).
        NSFileManager *manager = [NSFileManager defaultManager];
        NSURL* url = [[manager URLsForDirectory:NSDocumentDirectory
                                      inDomains:NSUserDomainMask] lastObject];
        NSURL* resultsDir = [url URLByAppendingPathComponent:@"GameLoopResults"
                                                 isDirectory:YES];
        [manager createDirectoryAtURL:resultsDir
          withIntermediateDirectories:NO
                           attributes:nil
                                error:nil];
    
        // Write the result message to a text file.
        NSURL* resultFile = [resultsDir URLByAppendingPathComponent:@"result.txt"];
        if ([manager fileExistsAtPath:[resultFile path]]) {
            // Append to the existing file
            NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:resultFile
                                                                     error:nil];
            [handle seekToEndOfFile];
            [handle writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
            [handle closeFile];
        } else {
            // Create and write to the file.
            [message writeToURL:resultFile
                     atomically:NO
                       encoding:NSUTF8StringEncoding error:nil];
        }
    }