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. 在您的應用清單,新的意圖過濾器添加到您的活動

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

    這允許測試實驗室通過以特定意圖觸發遊戲來啟動您的遊戲。

  2. 在您的代碼(我們建議裡面onCreate方法聲明),添加以下內容:

    爪哇

    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
    }

    科特林+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
    }

    這允許您的活動檢查啟動它的意圖。如果您願意,您也可以稍後添加此代碼(例如,在最初加載您的遊戲引擎之後)。

  3. 推薦:在測試結束時,添加:

    爪哇

    yourActivity.finish();

    科特林+KTX

    yourActivity.finish()

    當遊戲循環測試完成時,這將關閉您的應用程序。測試依賴於您的應用程序的 UI 框架來啟動下一個循環,關閉您的應用程序會告訴它測試已完成。

創建並運行遊戲循環測試

為遊戲循環測試配置應用後,您可以立即創建測試並在遊戲應用中運行它。您可以選擇運行使用無論是在測試實驗室的測試火力地堡控制台gcloud指令行界面(CLI) ,或在使用測試循環管理本地設備

在本地設備上運行

測試實驗室的測試循環管理器是一個開放源代碼的應用程序,可以幫助你融入遊戲循環測試,並在本地設備上運行它們。它還允許您的質量保證團隊在他們的設備上運行相同的遊戲循環。

要使用測試循環管理器在本地設備上運行測試:

  1. 下載測試循環經理手機或平板電腦上運行安裝:
    adb install testloopmanager.apk
  2. 在設備上,打開你的手機或平板電腦上測試環路應用的應用。該應用程序會在您的設備上顯示可與遊戲循環一起運行的應用程序列表。如果您在這裡看不到您的遊戲應用,請確保您的意圖過濾器匹配的第一個步驟中所描述的一個開始之前部分
  3. 選擇您的遊戲應用程序,然後選擇您要運行的循環次數。注意:在此步驟中,您可以選擇運行循環的子集,而不是僅運行一個循環。有關同時運行多個循環的詳細信息,請參閱可選功能。
  4. 點擊運行測試。您的測試立即開始運行。

在測試實驗室運行

您可以運行使用無論是在測試實驗室遊戲循環測試火力地堡控制台gcloud CLI。在開始之前,如果你還沒有準備好,打開火力地堡控制台並創建一個項目。

使用 Firebase 控制台

  1. 在火力地堡控制台,從左側面板中點擊測試實驗室
  2. 點擊運行第一個測試(或運行一個測試,如果你的項目以前運行測試)。
  3. 選擇遊戲循環作為測試類型,然後單擊繼續
  4. 點擊瀏覽,然後瀏覽到您的應用程序的.apk的文件。注意:在此步驟中,您可以選擇運行循環的子集,而不是僅運行一個循環。有關同時運行多個循環的詳細信息,請參閱可選功能。
  5. 點擊繼續
  6. 選擇用於測試您的應用的物理設備。
  7. 點擊開始測試

如需入門與火力地堡控制台的詳細信息,請參閱開始與火力地堡控制台測試。

使用 gcloud 命令行 (CLI)

  1. 如果你還沒有準備好,請下載並安裝谷歌雲SDK。

  2. 使用您的 Google 帳戶登錄 gcloud CLI:

    gcloud auth login

  3. 坐落在gcloud,你的火力地堡項目PROJECT_ID是你的火力地堡項目的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指令線測試。

可選功能

測試實驗室提供了多項可選功能,可讓您進一步自定義測試,包括寫入輸出數據的能力、對多個遊戲循環的支持以及相關循環的標籤。

寫入輸出數據

你的遊戲循環測試可以輸出寫入指定文件launchIntent.getData()方法。在運行測試後,您可以訪問火力地堡控制台的測試實驗室節這個輸出數據(參見遊戲循環測試輸出文件示例)。

測試實驗室遵循共享中所描述的應用程序之間的文件最佳實踐共享文件。在您的活動的onCreate()方法,在那裡你的意圖所在,你可以通過運行下面的代碼檢查數據的輸出文件:

爪哇

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

科特林+KTX

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

如果您想從遊戲應用程序的 C++ 端寫入文件,您可以傳入文件描述符而不是文件路徑:

爪哇

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

科特林+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);

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

輸出文件示例

您可以使用輸出數據文件(格式如下面的例子),在火力地堡控制台的測試實驗室部分顯示的遊戲循環測試結果。顯示領域/.../可以包含任何自定義字段,你需要,只要它們不與該文件中使用其他字段的名稱衝突:

{
  "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. 在測試循環管理器應用程序中,會出現一個選擇屏幕,讓您可以選擇要運行的循環。如果選擇多個循環,則在前一個循環完成後依次啟動每個循環。

  • 如果你正在運行與火力地堡控制台測試,輸入列表或一個範圍的方案領域的循環數。

  • 如果你正在運行與gcloud CLI測試,通過使用指定環路號的列表--scenario-numbers標誌。例如, --scenario-numbers=1,3,5運行迴路1,3,和5。

  • 如果您正在編寫 C++ 並希望更改循環的行為,請將以下額外內容傳遞給您的本機 C++ 代碼:

    爪哇

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

    科特林+KTX

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

    現在你可以改變你的循環的基礎上產生的行為int值。

標記遊戲循環

當您使用一個或多個場景標籤標記您的遊戲循環時,您和您的 QA 團隊可以輕鬆啟動一組相關的遊戲循環(例如,“所有兼容性遊戲循環”)並在單個矩陣中對其進行測試。您可以創建自己的標籤或使用測試實驗室提供的預定義標籤:

  • com.google.test.loops.player_experience :對於玩遊戲的時候用來再現一個真實的用戶體驗循環。使用這些循環進行測試的目的是找出真實用戶在玩遊戲時會遇到的問題。
  • com.google.test.loops.gpu_compatibility :對於用於測試GPU相關的問題循環。使用這些循環進行測試的目標是執行在生產中可能無法正常運行的 GPU 代碼,以暴露硬件和驅動程序的問題。
  • com.google.test.loops.compatibility :For循環用於測試廣泛的相容性問題,包括I / O問題和OpenSSL問題。
  • com.google.test.loops.performance :對於用於測試設備的性能的循環。例如,遊戲可能會在最複雜的圖形設置下運行,以查看新設備的行為方式。

要使您的應用程序能夠運行具有相同標籤的循環:

  • 如果您使用測試循環管理器運行測試:

    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. 在測試迴路管理應用程序,請在標籤字段設置一個或多個標籤。

  • 如果你正在運行與火力地堡控制台的測試,請在標籤字段設置一個或多個標籤。

  • 如果你正在運行與gcloud CLI測試,通過指定一個或多個場景標籤--scenario-labels標誌(例如, --scenario-labels=performance,gpu )。

應用許可支持

測試實驗室支持使用應用程序應用許可由谷歌提供的播放服務。要在使用測試實驗室測試您的應用程序時成功檢查許可,您必須將您的應用程序發佈到 Play 商店中的生產渠道。要使用測試實驗室在 Alpha 或 Beta 頻道中測試您的應用,請在將您的應用上傳到測試實驗室之前取消許可檢查。

已知的問題

測試實驗室中的遊戲循環測試存在以下已知問題:

  • 某些崩潰不支持回溯。例如,一些發布版本可以抑制的輸出debuggerd使用過程prctl(PR_SET_DUMPABLE, 0)要了解更多信息,請參閱debuggerd
  • 由於文件權限錯誤,當前不支持 API 級別 19。