Comece com os testes do Game Loop para iOS

Com os testes do Game Loop, você pode escrever testes nativos do seu mecanismo de jogo e executá-los no Test Lab nos dispositivos de sua escolha. Dessa forma, você não precisa se preocupar em escrever para diferentes UI ou estruturas de teste. Um teste de Game Loop simula as ações de um jogador real e, quando executado no Test Lab, fornece uma maneira rápida e escalonável de verificar se o jogo tem um bom desempenho para os usuários.

Esta página mostra como executar um teste de Game Loop e, em seguida, visualizar e gerenciar os resultados do teste na página Test Lab do console do Firebase. Você também pode personalizar ainda mais seus testes com recursos opcionais, como escrever resultados de testes personalizados ou encerrar seu teste antecipadamente .

O que é um teste de loop de jogo?

Um loop é uma execução total ou parcial do teste no aplicativo de jogos. Você pode executar um teste de Game Loop localmente em um simulador ou em um conjunto de dispositivos no Test Lab. Os testes de Game Loop podem ser usados ​​para:

  • Execute seu jogo como um usuário final o jogaria. Você pode criar um script para a entrada do usuário, deixá-lo ocioso ou substituí-lo por uma IA (por exemplo, se você implementou a IA em um jogo de corrida de carros, você pode colocar um piloto de IA encarregado da entrada do usuário) .

  • Execute seu jogo com a configuração de qualidade mais alta para descobrir quais dispositivos podem suportá-lo.

  • Execute um teste técnico, como compilar vários shaders, executá-los e verificar se o resultado é o esperado.

Etapa 1: registrar o esquema de URL personalizado do Test Lab

Primeiro, você deve registrar o esquema de URL personalizado do Firebase Test Lab no seu aplicativo:

  1. No Xcode, selecione um destino de projeto.

  2. Clique na guia Informações e adicione um novo tipo de URL .

  3. No campo Esquemas de URL , insira firebase-game-loop . Você também pode registrar o esquema de URL personalizado adicionando-o ao arquivo de configuração Info.plist do seu projeto em qualquer lugar dentro da 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>
    

Seu aplicativo agora está configurado para executar um teste usando o Test Lab.

Etapa 2 (opcional): configure seu aplicativo para executar vários loops

Se seu aplicativo tiver vários esquemas de URL personalizados registrados e você planeja executar vários loops (também conhecidos como cenários) em seu teste, deverá especificar quais loops deseja executar em seu aplicativo no momento da inicialização.

No delegado do seu aplicativo, substitua o método application(_:open:options:) :

Rápido

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
}

Objetivo-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 você executa vários loops no teste, o loop atual é passado como parâmetro para a URL usada para iniciar o aplicativo. Você também pode obter o número do loop atual analisando o objeto URLComponents usado para buscar o esquema de URL personalizado:

Rápido

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

Objetivo-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).
        }
    }
}

Etapa 3: crie e execute um teste

Depois de registrar o esquema de URL personalizado do Test Lab, você poderá executar o teste no Firebase console ou com a CLI gcloud beta . Se ainda não o fez, gere um arquivo IPA para seu aplicativo (você precisará localizá-lo mais tarde).

Execute um teste no console do Firebase

  1. Se ainda não o fez, abra o console do Firebase e crie um projeto.

  2. Na página Test Lab do console do Firebase, clique em Run Your First Test > Run an iOS Game Loop .

  3. Na seção Carregar aplicativo , clique em Procurar e selecione o arquivo IPA do seu aplicativo (se ainda não o fez, gere um arquivo IPA para seu aplicativo).

  4. Opcional : se desejar executar vários loops (também conhecidos como cenários) ao mesmo tempo ou selecionar loops específicos para execução, insira os números dos loops no campo Cenários .

    Por exemplo, quando você insere "1-3, 5", o Test Lab executa os loops 1, 2, 3 e 5. Por padrão (se você não inserir nada no campo Cenários ), o Test Lab executa apenas o loop 1.

  5. Na seção Dispositivos , selecione um ou mais dispositivos físicos nos quais deseja testar seu aplicativo e clique em Iniciar testes .

Execute um teste com a CLI gcloud beta

  1. Se ainda não o fez, configure seu ambiente local do SDK gcloud e instale o componente gcloud beta .

  2. Execute o comando gcloud beta firebase test ios run e use os seguintes sinalizadores para configurar a execução:

Sinalizadores para testes de Game Loop
--type

Obrigatório : especifica o tipo de teste do iOS que você deseja executar. Você pode inserir os tipos de teste xctest (padrão) ou game-loop .

--app

Obrigatório : caminho absoluto (Google Cloud Storage ou sistema de arquivos) para o arquivo IPA do seu aplicativo. Este sinalizador só é válido ao executar testes de Game Loop.

--scenario-numbers

Os loops (também conhecidos como cenários) que você deseja executar no seu aplicativo. Você pode inserir um loop, uma lista ou loops ou um intervalo de loops. O loop padrão é 1.

Por exemplo, --scenario-numbers=1-3,5 executa os loops 1, 2, 3 e 5.

--device-model

O dispositivo físico no qual você deseja executar o teste (descubra quais dispositivos disponíveis você pode usar).

--timeout

A duração máxima que você deseja que seu teste seja executado. Você pode inserir um número inteiro para representar a duração em segundos ou um número inteiro e uma enumeração para representar a duração como uma unidade de tempo mais longa.

Por exemplo:

  • --timeout=200 força o término do teste quando ele for executado por até 200 segundos.
  • --timeout=1h força o término do seu teste quando ele dura até uma hora.

Por exemplo, o comando a seguir executa um teste de Game Loop que executa os loops 1, 4, 6, 7 e 8 em um 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

Para obter mais informações sobre a CLI gcloud, consulte a documentação de referência .

Execute um teste localmente

Para executar seu teste localmente, carregue seu aplicativo de jogos em um simulador e execute:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • Você pode encontrar o UDID do seu simulador executando o comando instruments -s devices .

  • Se houver apenas um simulador em execução, insira a string especial "booted" no lugar de SIMULATOR_UDID .

Se o seu teste contiver vários loops, você poderá especificar qual loop deseja executar, passando o número do loop para o sinalizador scenario . Observe que você só pode executar um loop por vez ao executar o teste localmente. Por exemplo, se quiser executar os loops 1, 2 e 5, você deverá executar um comando separado para cada loop:

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

Terminar um teste mais cedo

Por padrão, um teste de Game Loop continua em execução até atingir o tempo limite de cinco minutos, mesmo quando todos os loops tiverem sido executados. Quando o tempo limite é atingido, o teste termina e cancela quaisquer loops pendentes. Você pode acelerar seu teste ou encerrá-lo mais cedo chamando o esquema de URL personalizado do Test Lab firebase-game-loop-complete no AppDelegate do seu aplicativo. Por exemplo:

Rápido

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

Objetivo-C

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

Seu teste de Game Loop encerra o loop atual e executa o próximo loop. Quando não houver mais loops para executar, o teste termina.

Escreva resultados de testes personalizados

Você pode configurar o teste do Game Loop para gravar resultados de testes personalizados no sistema de arquivos do seu dispositivo. Dessa forma, quando o teste começa a ser executado, o Test Lab armazena os arquivos de resultados em um diretório GameLoopsResults no seu dispositivo de teste (que você mesmo deve criar). Quando o teste termina, o Test Lab move todos os arquivos do diretório GameLoopResults para o bucket do seu projeto. Lembre-se do seguinte ao configurar seu teste:

  • Todos os arquivos de resultados são carregados independentemente do tipo, tamanho ou quantidade do arquivo.

  • O Test Lab não processa os resultados do teste até que todos os loops do teste tenham terminado de ser executados. Portanto, se o teste incluir vários loops que gravam a saída, anexe-os a um arquivo de resultados exclusivo ou crie um arquivo de resultados para cada loop. Dessa forma, você pode evitar a substituição dos resultados de um loop anterior.

Para configurar seu teste para gravar resultados de teste personalizados:

  1. No diretório Documents do seu aplicativo, crie um diretório chamado GameLoopResults .

  2. De qualquer lugar no código do seu aplicativo (por exemplo, no delegado do seu aplicativo), adicione o seguinte:

    Rápido

    /// 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.
      }
    }
    

    Objetivo-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];
        }
    }