開始使用遊戲迴圈測試

如果遊戲應用程式是使用不同的 UI 架構建構,就很難自動化遊戲測試。遊戲迴圈測試可讓您將原生測試與 Test Lab,並在所選裝置上輕鬆執行。遊戲迴圈測試會透過遊戲應用程式執行測試,同時模擬真實玩家的動作。本指南將說明如何執行 Game Loop 測試,然後在 Firebase 主控台中查看及管理測試結果。

視遊戲引擎而定,您可以針對單一或多個項目實作測試。 迴圈。迴圈是指測試的完整或部分執行 開發遊戲應用程式遊戲迴圈可用於:

  • 以使用者玩遊戲的方式執行遊戲關卡。您可以為使用者輸入內容編寫指令碼、讓使用者處於閒置狀態,或是在遊戲中以 AI 取代使用者 (例如,假設您有賽車遊戲應用程式,且已實作 AI)。您可以輕鬆 駕駛座 使用者輸入內容會不太一樣
  • 以最高品質設定執行遊戲,查看裝置是否支援該功能。
  • 執行技術測試 (編譯多個著色器、執行著色器、檢查輸出內容是否符合預期等)。

您可以在單一測試裝置、一組測試裝置,或 Test Lab 上執行遊戲迴圈測試。不過,我們不建議在虛擬裝置上執行 Game Loop 測試,因為虛擬裝置的圖形影格速率比實體裝置低。

事前準備

如要實作測試,您必須先為 Game Loop 測試設定應用程式。

  1. 在應用程式資訊清單中,將新的意圖篩選器新增至活動

    <activity android:name=".MyActivity">
       <intent-filter>
           <action android:name="com.google.intent.action.TEST_LOOP"/>
           <category android:name="android.intent.category.DEFAULT"/>
           <data android:mimeType="application/javascript"/>
       </intent-filter>
       <intent-filter>
          ... (other intent filters here)
       </intent-filter>
    </activity>
    

    這樣一來,Test Lab 就能透過特定意圖觸發遊戲,啟動遊戲。

  2. 在程式碼中 (建議在 onCreate 方法宣告內) 加入下列內容:

    Kotlin+KTX

    val launchIntent = intent
    if (launchIntent.action == "com.google.intent.action.TEST_LOOP") {
        val scenario = launchIntent.getIntExtra("scenario", 0)
        // Code to handle your game loop here
    }

    Java

    Intent launchIntent = getIntent();
    if(launchIntent.getAction().equals("com.google.intent.action.TEST_LOOP")) {
        int scenario = launchIntent.getIntExtra("scenario", 0);
        // Code to handle your game loop here
    }

    這可讓活動檢查啟動該活動的意圖。你也可以 如果您想要 (例如在初次載入遊戲之後),再新增這段程式碼, 引擎)。

  3. 建議做法:在測試結束時,新增:

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    遊戲迴圈測試完成後,應用程式就會關閉。這項測試仰賴 應用程式的 UI 架構來啟動下一個迴圈;關閉應用程式則代表 測試完成

建立及執行遊戲迴圈測試

設定應用程式進行遊戲迴圈測試後,您可以立即建立 並在遊戲應用程式中進行測試您可以選擇在 Test Lab (使用 Firebase 控制台gcloud) 指令列介面 (CLI),或在本機裝置上使用測試迴圈 管理員

在本機裝置上執行

Test LabTest Loop Manager 是開放原始碼應用程式,可協助您整合遊戲迴圈測試,並在本機裝置上執行這些測試。這也讓品質管控團隊可以在裝置上執行相同的遊戲迴圈。

如何使用測試迴圈管理員在本機裝置上執行測試:

  1. 下載測試迴圈管理工具 然後執行下列指令,即可進行安裝:
    adb install testloopmanager.apk
  2. 在裝置上開啟「測試迴圈應用程式」應用程式,或是 平板電腦。應用程式會顯示裝置上可透過遊戲迴圈執行的應用程式清單。如果這裡未顯示您的遊戲應用程式,請確認 您的意圖篩選器必須符合 「事前準備」一節
  3. 選取遊戲應用程式,然後選取要執行的迴圈數量。注意:在這一步中,您可以選擇執行部分迴圈,而非單一迴圈。如要進一步瞭解 同時執行多個迴圈,請參閱選用功能
  4. 按一下「Run test」。測試會立即開始執行。

Test Lab 中執行

您可以使用以下程式碼,在 Test Lab 中執行遊戲迴圈測試: Firebase 控制台gcloud CLI。使用前 請先開啟 Firebase 控制台,然後建立專案。

使用 Firebase 控制台

  1. Firebase 控制台中,按一下左側面板中的 Test Lab
  2. 按一下「Run Your First Test」。如果您的專案 或先前執行測試)。
  3. 選取「遊戲迴圈」做為測試類型,然後按一下「繼續」
  4. 按一下「瀏覽」,然後瀏覽應用程式的 .apk 檔案。注意:在這個步驟中,您可以選擇執行一部分迴圈 一個迴圈如要進一步瞭解如何一次執行多個迴圈,請參閱「選用功能」。
  5. 按一下「繼續」
  6. 選取要用來測試應用程式的實體裝置。
  7. 按一下「開始測試」

如要進一步瞭解如何開始使用 Firebase 主控台,請參閱「開始使用 Firebase 主控台進行測試」一文。

使用 gcloud 指令列 (CLI)

  1. 如果您尚未下載並安裝 Google Cloud SDK,請先下載並安裝

  2. 使用 Google 帳戶登入 gcloud CLI:

    gcloud auth login

  3. 在 gcloud 中設定 Firebase 專案,其中 PROJECT_ID 是 Firebase 專案的 ID:

    gcloud config set project PROJECT_ID
    
  4. 執行第一項測試:

    gcloud firebase test android run \
     --type=game-loop --app=<var>path-to-apk</var> \
     --device model=herolte,version=23
    

如要進一步瞭解如何開始使用 gcloud CLI,請參閱 透過 gcloud 指令列開始測試。

選用功能

Test Lab 提供多項選用功能,可讓您進一步自訂測試,包括寫入輸出資料、支援多個遊戲迴圈,以及相關迴圈的標籤。

寫入輸出資料

遊戲迴圈測試可將輸出內容寫入 launchIntent.getData() 方法。執行測試後,您可以存取 Firebase 控制台的 Test Lab 區段輸出資料 (請參閱 遊戲迴圈測試輸出檔案範例)。

Test Lab 遵循「共用檔案」一文中所述的應用程式間檔案共用最佳做法。在意圖所在的活動 onCreate() 方法中,您可以執行以下程式碼,檢查資料輸出檔案:

Kotlin+KTX

val launchIntent = intent
val logFile = launchIntent.data
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    // ...
}

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    // ...
}

如要從遊戲應用程式的 C++ 端寫入檔案,您可以 傳入檔案描述元而非檔案路徑:

Kotlin+KTX

val launchIntent = intent
val logFile = launchIntent.data
var fd = -1
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    fd = try {
        contentResolver
            .openAssetFileDescriptor(logFile, "w")!!
            .parcelFileDescriptor
            .fd
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
        -1
    } catch (e: NullPointerException) {
        e.printStackTrace()
        -1
    }
}

// C++ code invoked here.
// native_function(fd);

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
int fd = -1;
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    try {
        fd = getContentResolver()
                .openAssetFileDescriptor(logFile, "w")
                .getParcelFileDescriptor()
                .getFd();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fd = -1;
    } catch (NullPointerException e) {
        e.printStackTrace();
        fd = -1;
    }
}

// C++ code invoked here.
// native_function(fd);

C++

#include <unistd.h>
JNIEXPORT void JNICALL
Java_my_package_name_MyActivity_native_function(JNIEnv *env, jclass type, jint log_file_descriptor) {
// The file descriptor needs to be duplicated.
int my_file_descriptor = dup(log_file_descriptor);
}

輸出檔案範例

您可以使用輸出資料檔案 (格式如以下範例所示),在 Firebase 主控台的 Test Lab 部分顯示遊戲迴圈測試結果。顯示為 /.../ 的區域可以包含您需要的任何自訂欄位,只要這些欄位名稱不會與此檔案中使用的其他欄位名稱衝突即可:

{
  "name": "test name",
  "start_timestamp": 0, // Timestamp of the test start (in us).
                           Can be absolute or relative
  "driver_info": "...",
  "frame_stats": [
    {
      "timestamp": 1200000, // Timestamp at which this section was written
                               It contains value regarding the period
                               start_timestamp(0) -> this timestamp (1200000 us)
      "avg_frame_time": 15320, // Average time to render a frame in ns
      "nb_swap": 52, // Number of frame rendered
      "threads": [
        {
          "name": "physics",
          "Avg_time": 8030 // Average time spent in this thread per frame in us
        },
        {
          "name": "AI",
          "Avg_time": 2030 // Average time spent in this thread per frame in us
        }
      ],
      /.../ // Any custom field you want (vertices display on the screen, nb units …)
    },
    {
      // Next frame data here, same format as above
    }
  ],
  "loading_stats": [
    {
      "name": "assets_level_1",
      "total_time": 7850, // in us
      /.../
    },
    {
      "name": "victory_screen",
      "total_time": 554, // in us
      /.../
    }

  ],
  /.../, // You can add custom fields here
}

多個遊戲迴圈

您可能發現,在應用程式中執行多個遊戲迴圈,是相當實用的做法。迴圈是一種 您的遊戲應用程式 從頭到尾完成整個間隔舉例來說,如果遊戲中有許多關卡,您可能會想使用一個遊戲迴圈來啟動每個關卡,而不是使用一個迴圈來逐一執行所有關卡。這樣一來,如果應用程式在第 32 層發生當機,您可以直接啟動該遊戲迴圈來重現當機情形,並測試錯誤修正。

如要讓應用程式一次執行多個迴圈:

  • 使用測試迴圈管理員執行測試:

    1. 在應用程式的資訊清單中,加入以下這行程式碼: <application> 元素:

      <meta-data
        android:name="com.google.test.loops"
        android:value="5" />
      

      此啟動意圖包含目標迴圈做為整數參數。於 在 android:value 欄位中,您可以指定介於 1 到 1024 之間的整數 ( 單一測試允許迴圈數量上限)。注意事項 系統會從 1 開始為迴圈建立索引,而非從 0 開始建立索引。

    2. 在「Test Loop Manager」應用程式中,系統會顯示選取畫面,讓您選取要執行的迴圈。如果您選取多個迴圈,系統會在前一個迴圈完成後依序啟動每個迴圈。

  • 如果您是透過 Firebase 控制台執行測試,請輸入清單或 「Scenario」欄位中的循環編號範圍。

  • 如果您要使用 gcloud CLI 執行測試,請使用 --scenario-numbers 標記指定一組迴圈數。例如: --scenario-numbers=1,3,5 會執行迴圈 1、3 和 5。

  • 如果您要編寫 C++ 程式碼,並想變更迴圈的行為,請將下列額外項目傳遞至原生 C++ 程式碼:

    Kotlin+KTX

    val launchIntent = intent
    val scenario = launchIntent.getIntExtra("scenario", 0)

    Java

    Intent launchIntent = getIntent();
    int scenario = launchIntent.getIntExtra("scenario", 0);

    您現在可以根據產生的 int 值,變更迴圈的行為。

標記遊戲迴圈

當您為遊戲迴圈加上一或多個情境標籤時,您和品質確保團隊就能輕鬆啟動一組相關的遊戲迴圈 (例如 「所有相容性」 遊戲迴圈),並在單一矩陣中測試這些迴圈。您可以建立自己的標籤,也可以 請使用 Test Lab 提供的預先定義標籤:

  • com.google.test.loops.player_experience:用於重現使用者玩遊戲時的實際體驗。使用這些迴圈進行測試的目的,是找出真實使用者在玩遊戲時可能會遇到的問題。
  • com.google.test.loops.gpu_compatibility:For 迴圈,用於測試與 GPU 相關的問題。測試使用這些迴圈的目的是要執行 GPU 可能無法在正式環境中正確執行 以便找出 硬體和驅動程式
  • com.google.test.loops.compatibility:用於測試 多種相容性問題,包括 I/O 問題和 OpenSSL 以負載平衡機制分配流量 即可降低應用程式發生效能問題的風險
  • com.google.test.loops.performance:For 迴圈,用於測試裝置的效能。舉例來說,遊戲可能會在最複雜的 圖像設定來查看新裝置的運作方式。

如要讓應用程式以相同標籤執行迴圈,請按照下列步驟操作:

  • 如果您使用測試迴圈管理程式執行測試,請按照下列步驟操作:

    1. 在應用程式的資訊清單中,新增下列中繼資料行,並將 LABEL_NAME 替換為您選擇的標籤:

      <meta-data
       android:name="com.google.test.loops.LABEL_NAME"
       android:value="1,3-5" />
      

      android:value 欄位中,您可以指定 1 到 1024 的範圍或一組整數 (單一測試允許的迴圈上限),代表您要標示的迴圈。請注意,迴圈會從 從 1,而不是 0。例如,android:value="1,3-5" 會將 LABEL_NAME 套用至迴圈 1、3、4 和 5。

    2. 在 Test Loop Manager 應用程式中,在「Labels」欄位中輸入一或多個標籤。

  • 如果您是使用 Firebase 資訊主頁執行測試,請在「Labels」欄位中輸入一或多個標籤。

  • 如果您要使用 gcloud CLI 執行測試,請指定 一或多個情境標籤 --scenario-labels 旗標 (例如 --scenario-labels=performance,gpu)。

應用程式授權支援

Test Lab 支援使用 Google Play 提供的應用程式授權服務的應用程式。如要使用 Test Lab 測試應用程式時成功檢查授權,您必須將應用程式發布至 Play 商店的正式版管道。如要使用 Alpha 版或 Beta 版測試應用程式 Test Lab,請先移除授權檢查,再將應用程式上傳至 Test Lab

已知問題

Test Lab 中的遊戲迴圈測試有以下已知問題:

  • 部分當機情形不支援回溯追蹤。舉例來說,某些發布子版本 使用以下程式碼隱藏 debuggerd 程序的輸出內容 prctl(PR_SET_DUMPABLE, 0)。詳情請參閱 debuggerd
  • 由於檔案權限錯誤,目前不支援 API 級別 19。