ゲームループテストを実行する

ゲームアプリが異なるUIフレームワーク上に構築されている場合、ゲームテストを自動化するのは難しい場合があります。ゲームループテストを使用すると、ネイティブテストをTest Labと統合して、選択したデバイスで簡単に実行できます。このガイドでは、Firebase Test Lab を使用して実行するゲーム ループ テストを準備する方法について説明します。

ゲーム ループ テストについて

ゲーム ループ テストとは何ですか?

ゲーム ループ テストは、実際のプレーヤーのアクションをシミュレートして、ゲームが高速かつスケーラブルな方法でユーザーにとって適切に機能することを確認します。ループは、ゲームアプリでのテストの完全または部分的な実行です。ゲーム ループ テストは、シミュレーターまたは Test Lab の一連のデバイスでローカルに実行できます。ゲーム ループ テストは、次の目的で使用できます。

  • エンド ユーザーがプレイするようにゲームを実行します。ユーザーの入力をスクリプト化するか、ユーザーをアイドル状態にするか、ユーザーを AI に置き換えることができます (たとえば、カー レース ゲームに AI を実装した場合、AI ドライバーにユーザーの入力を任せることができます)。 .
  • 最高品質の設定でゲームを実行して、それをサポートできるデバイスを見つけます。
  • 複数のシェーダーをコンパイルして実行し、出力が期待どおりであることを確認するなど、技術的なテストを実行します。

ステップ 1 : Test Lab のカスタム URL スキームを登録する

  1. Xcode で、プロジェクト ターゲットを選択します。

  2. [情報] タブをクリックし、新しいURL タイプを追加します。

  3. URL スキームフィールドに、 firebase-game-loopと入力します。プロジェクトのInfo.plist構成ファイルの<dict>タグ内の任意の場所に追加して、カスタム URL スキームを登録することもできます。

    <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>
    

これで、Test Lab を使用してテストを実行するようにアプリが構成されました。

ステップ 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).
        }
    }
}

テストを早めに終了する

デフォルトでは、すべてのループが実行された場合でも、ゲーム ループ テストは 5 分のタイムアウトに達するまで実行を続けます。タイムアウトに達すると、テストが終了し、保留中のループがキャンセルされます。アプリの AppDelegate で Test Lab のカスタム URL スキーム firebase 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) {}];
}

ゲーム ループ テストは現在のループを終了し、次のループを実行します。実行するループがなくなると、テストは終了します。

カスタム テスト結果の書き込み

ゲーム ループ テストを構成して、カスタム テスト結果をデバイスのファイル システムに書き込むことができます。このようにして、テストの実行が開始されると、Test Lab はテスト デバイス (自分で作成する必要があります) のGameLoopsResultsディレクトリに結果ファイルを保存します。テストが終了すると、Test Lab はすべてのファイルをGameLoopResultsディレクトリからプロジェクトのバケットに移動します。テストを設定するときは、次の点に注意してください。

  • ファイルの種類、サイズ、数量に関係なく、すべての結果ファイルがアップロードされます。

  • Test Lab は、テスト内のすべてのループの実行が完了するまでテスト結果を処理しません。そのため、出力を書き込む複数のループがテストに含まれている場合は、それらを一意の結果ファイルに追加するか、ループごとに結果ファイルを作成してください。このようにして、前のループからの結果を上書きすることを避けることができます。

カスタム テスト結果を書き込むようにテストを設定するには:

  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. 表示されるドロップダウン メニューから、[製品] > [アーカイブ] をクリックします。最新のアーカイブを選択し、[ Distribute App ] をクリックします。

  3. 表示されるウィンドウで、[開発] > [次へ] をクリックします。

  4. オプション:ビルドを高速化するには、[ビットコードから再構築] オプションの選択を解除し、[次へ] をクリックします。 Test Lab では、テストを実行するためにアプリを薄くしたり再構築したりする必要がないため、このオプションを安全に無効にすることができます。

  5. [エクスポート]をクリックし、アプリの IPA ファイルをダウンロードするディレクトリを入力します。

ステップ 4 : テストをローカルで実行する

Test Lab でテストを実行する前に、ローカルでテストを実行して動作を確認できます。ローカルでテストするには、ゲーム アプリをシミュレーターにロードして実行します。

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • シミュレーターの UDID は、 instruments -s devicesコマンドを実行して確認できます。

  • 実行中のシミュレータが 1 つしかない場合は、 SIMULATOR_UDIDの代わりに特別な文字列"booted"を入力します。

テストに複数のループが含まれている場合、ループ番号をscenarioフラグに渡すことで、実行するループを指定できます。テストをローカルで実行する場合は、一度に 1 つのループしか実行できないことに注意してください。たとえば、ループ 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を使用してテストを実行します。