Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

運行遊戲循環測試

當遊戲應用程序構建在不同的 UI 框架上時,遊戲測試自動化可能很困難。遊戲循環測試允許您將本機測試與測試實驗室集成,並在您選擇的設備上輕鬆運行它們。本指南介紹瞭如何使用 Firebase 測試實驗室準備要運行的遊戲循環測試。

關於遊戲循環測試

什麼是遊戲循環測試?

遊戲循環測試模擬真實玩家的動作,以快速且可擴展的方式驗證您的遊戲是否對用戶表現良好。循環是對遊戲應用程序測試的全部或部分運行。您可以在模擬器或測試實驗室中的一組設備上本地運行遊戲循環測試。遊戲循環測試可用於:

  • 像最終用戶一樣運行您的遊戲。您可以編寫用戶輸入的腳本,讓用戶閒置,或者用 AI 替換用戶(例如,如果您在賽車遊戲中實現了 AI,則可以讓 AI 驅動程序負責用戶的輸入) .
  • 以最高質量設置運行您的遊戲,以找出哪些設備可以支持它。
  • 運行技術測試,例如編譯多個著色器、執行它們並檢查輸出是否符合預期。

第1步:註冊測試實驗室的自定義URL方案

  1. 在 Xcode 中,選擇一個項目目標。

  2. 單擊信息選項卡,然後添加一個新的URL類型

  3. URL方案字段中輸入firebase-game-loop 。您也可以通過將其添加到項目的註冊自定義URL方案Info.plist的內部配置文件中的任何地方<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>
    

您的應用現已配置為使用測試實驗室運行測試。

第2步:可選配置應用

運行多個循環

如果您計劃在測試中運行多個循環(也稱為場景),則必須指定要在啟動時在應用程序中運行的循環。

在您的應用程序的委託,重寫application(_:open:options:)方法:

迅速

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
}

目標-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:).
  }
}

當您在測試中運行多個循環時,當前循環將作為參數傳遞給用於啟動應用程序的 URL。您也可以通過分析獲得的電流迴路數URLComponents對象用於獲取自定義URL方案:

迅速

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

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

提前結束測試

默認情況下,遊戲循環測試會繼續運行,直到達到五分鐘的超時,即使所有循環都已執行。達到超時後,測試結束並取消任何掛起的循環。您可以加快您的測試或致電測試實驗室的自定義URL方案,提前結束其firebase-game-loop-complete應用程式的AppDelegate中。例如:

迅速

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

目標-C

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

您的遊戲循環測試會終止當前循環並執行下一個循環。當沒有更多的循環運行時,測試結束。

編寫自定義測試結果

您可以配置遊戲循環測試以將自定義測試結果寫入設備的文件系統。這樣一來,當測試開始運行,測試實驗室保存的結果文件GameLoopsResults目錄您的測試設備上(你必須自己創建)。當測試結束後,測試實驗室從移動所有文件GameLoopResults目錄到項目的水桶。設置測試時請記住以下幾點:

  • 無論文件類型、大小或數量如何,都會上傳所有結果文件。

  • 在測試中的所有循環都完成運行之前,測試實驗室不會處理您的測試結果,因此如果您的測試包含多個寫入輸出的循環,請確保將它們附加到唯一的結果文件或為每個循環創建一個結果文件。這樣,您可以避免覆蓋先前循環的結果。

要設置測試以編寫自定義測試結果:

  1. 在您的應用程序的Documents目錄下創建一個名為GameLoopResults

  2. 從您應用程序代碼的任何位置(例如,您的應用程序委託),添加以下內容:

    迅速

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

    目標-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];
        }
    }
    

第3步:您打包用於上傳應用程序

最後,為您的應用生成一個 IPA 文件(稍後您需要找到它)。

  1. 在 Xcode 中,為目標應用程序選擇一個配置文件。

  2. 從下拉菜單中出現,單擊產品>存檔。選擇最新的歸檔,然後單擊分發應用程序

  3. 在出現的窗口中,單擊開發>下一步

  4. 可選:要獲得更快的構建,取消選項位碼重建,然後單擊下一步。測試實驗室不需要精簡或重建您的應用程序來運行測試,因此您可以安全地禁用此選項。

  5. 單擊導出,然後輸入要下載你的應用程序的IPA文件的目錄。

第4步:運行在本地測試

在使用測試實驗室運行之前,您可以在本地運行測試以檢查其行為。要在本地進行測試,請在模擬器中加載您的遊戲應用程序並運行:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • 您可以通過運行找到你的模擬器的UDID instruments -s devices命令。

  • 如果只有一個模擬器中運行,進入特殊字符串"booted"代替SIMULATOR_UDID

如果您的測試包含多個循環,你可以通過迴路數到指定要運行該循環scenario標誌。請注意,在本地運行測試時,一次只能運行一個循環。例如,如果要運行循環 1、2 和 5,則必須為每個循環運行單獨的命令:

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

下一步

運行使用您的測試火力地堡控制台gcloud CLI