Può essere difficile automatizzare i test dei giochi quando le app di gioco sono basate su framework UI diversi. I test del ciclo di gioco ti consentono di integrare i test nativi con Test Lab ed eseguirli facilmente sui dispositivi che selezioni. Questa guida descrive come preparare un test del ciclo di gioco da eseguire utilizzando Firebase Test Lab.
Informazioni sui test del ciclo di gioco
Che cos'è un test del ciclo di gioco?
Un test del ciclo di gioco simula le azioni di un giocatore reale per verificare che il gioco funzioni bene per gli utenti in modo rapido e scalabile. Un ciclo è un'esecuzione completa o parziale del test sull'app di gioco. Puoi eseguire un test del ciclo di gioco localmente su un simulatore o su un insieme di dispositivi in Test Lab. I test del 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 mettere un pilota AI a capo dell'input dell'utente).
- Eseguire il gioco con l'impostazione di qualità più alta per scoprire quali dispositivi possono supportarlo.
- Eseguire un test tecnico, ad esempio compilando più shader, eseguendoli e verificando che l'output sia quello previsto.
Passaggio 1: registra lo schema URL personalizzato di Test Lab
In Xcode, seleziona una destinazione del progetto.
Fai clic sulla scheda Informazioni, quindi aggiungi un nuovo tipo di URL.
Nel campo Schemi URL, inserisci
firebase-game-loop. Puoi anche registrare lo schema URL personalizzato aggiungendolo al file di configurazioneInfo.plistdel 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>
Ora l'app è configurata per eseguire un test utilizzando Test Lab.
Passaggio 2: (facoltativo) configura l'app
Esegui più cicli
Se prevedi di eseguire più cicli (ovvero scenari) nel test, devi specificare quali cicli vuoi eseguire nell'app al momento dell'avvio.
Nel delegato dell'app, 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 <UIApplicationOpenURLOptionsKey, id> *)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 a
parametro all'URL utilizzato per avviare l'app. Puoi anche ottenere il numero del ciclo
corrente analizzando l'
URLComponents oggetto 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).
}
}
}
Termina un test in anticipo
Per impostazione predefinita, un test del 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 del 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 del ciclo di gioco in modo che scriva i 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à di file.
Test Lab non elabora i risultati del test finché non sono stati eseguiti tutti i cicli del test. Pertanto, se il test include più cicli che scrivono l'output, assicurati di aggiungerli a un file dei risultati univoco o di creare un file dei 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 i risultati di test personalizzati:
Nella directory
Documentsdell'app, crea una directory denominataGameLoopResults.Da qualsiasi punto del codice dell'app (ad es. il delegato dell'app), 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]; } }
Passaggio 3: firma l'app
Assicurati che tutti gli artefatti dell'app siano firmati. Ad esempio, puoi farlo tramite Xcode specificando le impostazioni di firma come il profilo di provisioning e l'identità. Per ulteriori informazioni, vedi: Firma del codice Apple
Passaggio 4: crea il pacchetto dell'app per il caricamento
Genera un file IPA per l'app (dovrai individuarlo in un secondo momento).
Dal menu a discesa visualizzato, fai clic su Prodotto > Archivio. Seleziona l'archivio più recente, quindi fai clic su Distribuisci app.
Nella finestra visualizzata, fai clic su Sviluppo > Avanti.
Fai clic su Esporta, quindi inserisci una directory in cui vuoi scaricare il file IPA dell'app.
Passaggio 5: verifica la firma dell'app
- Verifica la firma dell'app decomprimendo il file .ipa ed eseguendo
codesign --verify --deep --verbose /path/to/MyApp.appdove "MyApp" è il nome dell'app all'interno della cartella decompressa (varia per ogni progetto). L'output previsto èMyApp.app: valid on disk.
Passaggio 6: esegui il test localmente
Puoi eseguire il test localmente per verificarne il comportamento prima di eseguirlo con Test Lab. 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
instruments -s devicescomando.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=1xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5
Passaggi successivi
Esegui il test utilizzando la Firebase console o la gcloud CLI.