以不同的 UI 架構建構遊戲應用程式時,可能很難自動執行遊戲測試。遊戲迴圈測試可讓您將原生測試與 Test Lab 整合,並在您選取的裝置上輕鬆執行。遊戲迴圈測試會在遊戲應用程式中執行測試,並模擬真實玩家的動作。本指南說明如何執行遊戲迴圈測試,然後在 Firebase 控制台中查看及管理測試結果。
視遊戲引擎而定,您可以使用單次或多次迴圈實作測試。迴圈是指在遊戲應用程式中完整或部分測試的執行過程。遊戲迴圈的用途如下:
- 請以使用者玩遊戲的方式執行遊戲關卡。您可以根據使用者的輸入內容編寫指令碼、讓使用者處於閒置狀態,或是以 AI 取代使用者為遊戲中的合適做法 (例如,假設您有一個賽車遊戲應用程式,且已導入 AI)。你可以輕鬆讓 AI 驅動器 控管使用者輸入內容
- 以最高品質的設定執行遊戲,確認裝置是否支援該遊戲。
- 執行技術測試,例如編譯多個著色器、執行這些著色器、檢查輸出內容是否符合預期等。
您可以在單一測試裝置、一組測試裝置或 Test Lab 上執行遊戲迴圈測試。不過,我們不建議在虛擬裝置上執行遊戲迴圈測試,因為這類裝置的圖形影格速率低於實體裝置。
事前準備
如要實作測試,您必須先針對遊戲迴圈測試設定應用程式。
在應用程式資訊清單中,將意圖篩選器新增至活動:
<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 即可透過特定意圖觸發遊戲。
在程式碼 (建議將
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 }
如此一來,活動就能查看啟動活動的意圖。如有需要,您之後也可以視需要新增這段程式碼 (例如在初始載入遊戲引擎後)。
建議做法:請在測試結束時新增:
Kotlin+KTX
yourActivity.finish()
Java
yourActivity.finish();
這樣會在遊戲迴圈測試完成後關閉應用程式。這項測試需要使用應用程式的 UI 架構啟動下一個迴圈,而關閉應用程式會顯示測試已完成。
建立及執行遊戲迴圈測試
設定應用程式進行遊戲迴圈測試後,可以立即在遊戲應用程式中建立測試並執行測試。您可以選擇使用 Firebase 控制台或 gcloud 指令列介面 (CLI),或是在使用測試迴圈管理工具的本機裝置上執行測試。
在本機裝置上執行
Test Lab 的測試迴圈管理工具是一款開放原始碼應用程式,可協助您整合遊戲迴圈測試,並在您的本機裝置上執行。品質保證團隊也能在他們的裝置上執行相同的遊戲迴圈。
如何使用「測試迴圈管理工具」在本機裝置上執行測試:
- 在手機或平板電腦上下載測試迴圈管理員,並執行下列指令來安裝:
adb install testloopmanager.apk
- 在裝置上,開啟手機或平板電腦的「測試迴圈應用程式」應用程式。應用程式會在裝置上顯示可透過遊戲迴圈執行的應用程式清單。如果此處未顯示您的遊戲應用程式,請確認您的意圖篩選器與「事前準備」部分步驟中說明的意圖篩選器相符。
- 選取您的遊戲應用程式,然後選取要執行的迴圈數量。注意:在這個步驟中,您可以選擇執行一部分迴圈,而非只執行一個迴圈。如要進一步瞭解如何一次執行多個迴圈,請參閱選用功能。
- 按一下「Run test」。測試會立即開始執行。
在 Test Lab 中執行
您可以使用 Firebase 控制台或 gcloud CLI,在 Test Lab 中執行遊戲迴圈測試。在開始之前,請先開啟 Firebase 主控台並建立專案。
使用 Firebase 控制台
- 在 Firebase 控制台中,按一下左側面板中的「Test Lab」。
- 按一下「Run Your First Test」;如果專案先前已執行過測試,請按一下「Run a Test」。
- 選取「遊戲迴圈」做為測試類型,然後按一下「繼續」。
- 按一下「Browse」,然後前往應用程式的
.apk
檔案。注意:在這個步驟中,您可以選擇執行一部分迴圈,而非只執行一個迴圈。如要進一步瞭解如何一次執行多個迴圈,請參閱選用功能。 - 點選「繼續」。
- 選取要用來測試應用程式的實體裝置。
- 按一下「Start Tests」。
如要進一步瞭解如何開始使用 Firebase 控制台,請參閱「透過 Firebase 控制台開始測試」。
使用 gcloud 指令列 (CLI)
請下載並安裝 Google Cloud SDK (如果尚未下載)
使用 Google 帳戶登入 gcloud CLI:
gcloud auth login
在 gcloud 中設定 Firebase 專案,其中
PROJECT_ID
是 Firebase 專案的 ID:gcloud config set project PROJECT_ID
執行第一項測試:
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 關時當機,您可以直接啟動遊戲迴圈來重現當機問題及測試錯誤修正。
如要讓應用程式一次執行多個迴圈:
如果透過「測試迴圈管理工具」執行測試:
在應用程式的資訊清單 (位於
<application>
元素中) 加入以下這行程式碼:<meta-data android:name="com.google.test.loops" android:value="5" />
這個啟動意圖含有目標迴圈的整數參數。在
android:value
欄位中,您可以指定 1 到 1024 之間的整數 (單一測試允許的迴圈數量上限)。請注意,迴圈是從 1 開始建立索引,而非 0。「測試迴圈管理員」應用程式會顯示選取畫面,方便您選取要執行的迴圈。如果您選取多個迴圈,則每個迴圈都會在前一個迴圈完成後依序啟動。
如果您使用 Firebase 主控台執行測試,請在「Scenarios」(情境) 欄位中輸入清單或一系列迴圈編號。
如要透過 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
:適用於用來測試 GPU 相關問題的迴圈。使用這些迴圈進行測試的目的,是執行可能無法在實際工作環境中正確執行的 GPU 程式碼,以曝露硬體和驅動程式的問題。com.google.test.loops.compatibility
:適用於用於測試各種相容性問題的迴圈,包括 I/O 問題和 OpenSSL 問題。com.google.test.loops.performance
:適用於用於測試裝置效能的迴圈。舉例來說,遊戲可能會在最複雜的圖形設定中執行,藉此瞭解新裝置的行為。
如要讓應用程式使用相同標籤執行迴圈:
如果透過「測試迴圈管理工具」執行測試:
在應用程式資訊清單中,新增下列中繼資料行,並將 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。在測試迴圈管理員應用程式的「Labels」(標籤) 欄位中輸入一或多個標籤。
如果您使用 Firebase 主控台執行測試,請在「Labels」(標籤) 欄位中輸入一或多個標籤。
如要透過 gcloud CLI 執行測試,請使用
--scenario-labels
標記指定一或多個情境標籤 (例如--scenario-labels=performance,gpu
)。
應用程式授權支援
Test Lab 支援使用 Google Play 提供的應用程式授權服務的應用程式。如要在使用 Test Lab 測試應用程式時成功檢查授權,您必須將應用程式發布到 Play 商店的正式版管道。如要使用 Test Lab 在 Alpha 或 Beta 版中測試應用程式,請先移除授權檢查,再將應用程式上傳到 Test Lab。
已知問題
Test Lab 的遊戲迴圈測試有下列已知問題:
- 部分當機問題不支援返回追蹤記錄。舉例來說,部分發布子版本可能會使用
prctl(PR_SET_DUMPABLE, 0)
隱藏debuggerd
程序的輸出內容。詳情請參閱debuggerd
。 - 由於檔案權限錯誤,目前不支援 API 級別 19。