Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

運行遊戲循環測試

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

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

關於遊戲循環測試

什麼是遊戲循環測試?

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

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

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

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

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

  3. URL Schemes字段中,輸入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
}

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

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

迅速

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

提前結束測試

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

迅速

/// 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) {}];
}

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

編寫自定義測試結果

您可以配置 Game Loop 測試以將自定義測試結果寫入設備的文件系統。這樣,當測試開始運行時,測試實驗室將結果文件存儲在測試設備上的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.
      }
    }
    

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

第 3 步:打包您的應用以進行上傳

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

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

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

  3. 在出現的窗口中,單擊Development > Next

  4. 可選:要獲得更快的構建,請取消選擇Rebuild from Bitcode選項,然後單擊Next 。測試實驗室不需要精簡或重建您的應用程序即可運行測試,因此您可以安全地禁用此選項。

  5. 點擊Export ,然後輸入您要在其中下載應用程序的 IPA 文件的目錄。

第 4 步:在本地運行測試

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

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

  • 如果只有一個模擬器在運行,輸入特殊字符串"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

下一步

使用Firebase 控制台gcloud CLI運行測試。