יכול להיות שיהיה קשה להפוך את בדיקת המשחקים לאוטומטית אם אפליקציות המשחקים מבוססות על מסגרות שונות של ממשק משתמש. בדיקות Game Loop מאפשרות לכם לשלב את הבדיקות המקוריות שלכם עם Test Lab ולהריץ אותן בקלות במכשירים שתבחרו. בדיקת game loop מריצה את הבדיקה באפליקציית המשחקים תוך סימולציה של פעולות של שחקן אמיתי. במדריך הזה נסביר איך להריץ בדיקה של game loop, ואז להציג ולנהל את תוצאות הבדיקה במסוף Firebase.
בהתאם למנוע המשחק, אפשר להטמיע בדיקות עם לולאה אחת או כמה לולאות. לולאה היא הרצה מלאה או חלקית של הבדיקה באפליקציית המשחק. אפשר להשתמש בלולאות של משחקים כדי:
- מריצים שלב במשחק כמו שמשתמש קצה היה מריץ אותו. אתם יכולים לכתוב סקריפט לקלט של המשתמש, לאפשר למשתמש להיות במצב בלי פעילות או להחליף את המשתמש ב-AI אם זה הגיוני במשחק שלכם (לדוגמה, אם יש לכם אפליקציית משחקים של מכוניות מירוץ וכבר הטמעתם AI). אתם יכולים בקלות להעביר את האחריות על הקלט של המשתמש לנהג AI.
- כדי לבדוק אם המכשירים תומכים בהגדרה הזו, מריצים את המשחק בהגדרת האיכות הכי גבוהה.
- להריץ בדיקה טכנית (קומפילציה של כמה הצללות, הפעלה שלהן, בדיקה שהפלט הוא כמו שציפיתם וכו').
אפשר להריץ בדיקה של לולאת משחק במכשיר בדיקה יחיד, בקבוצה של מכשירי בדיקה או ב-Test Lab. עם זאת, לא מומלץ להריץ בדיקות של Game Loop במכשירים וירטואליים, כי קצב הפריימים של הגרפיקה בהם נמוך יותר מאשר במכשירים פיזיים.
לפני שמתחילים
כדי להטמיע בדיקה, צריך קודם להגדיר את האפליקציה לבדיקות של game loop.
בקובץ מניפסט של האפליקציה, מוסיפים מסנן Intent חדש לפעילות:
<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
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
yourActivity.finish()
Java
yourActivity.finish();
האפליקציה תיסגר בסיום הבדיקה של לולאת המשחק. הבדיקה מסתמכת על מסגרת ממשק המשתמש של האפליקציה כדי להתחיל את הלולאה הבאה, וסגירת האפליקציה מציינת שהבדיקה הסתיימה.
יצירה והפעלה של בדיקת Game Loop
אחרי שמגדירים את האפליקציה לבדיקות של לולאות משחק, אפשר ליצור בדיקה ולהריץ אותה באפליקציית המשחק באופן מיידי. אפשר להריץ בדיקה ב-Test Lab באמצעות מסוף Firebase או ממשק שורת הפקודה (CLI) של gcloud, או במכשיר מקומי באמצעות Test Loop Manager.
הרצה במכשיר מקומי
Test LabTest Loop Manager של Test Lab היא אפליקציה בקוד פתוח שעוזרת לשלב בדיקות של game loop ולהריץ אותן במכשירים המקומיים. היא גם מאפשרת לצוות בקרת האיכות להריץ את אותם לולאות משחק במכשירים שלהם.
כדי להריץ בדיקה במכשיר מקומי באמצעות Test Loop Manager:
- מורידים את Test Loop Manager לטלפון או לטאבלט ומתקינים אותו באמצעות הפקודה:
adb install testloopmanager.apk
- במכשיר, פותחים את האפליקציה Test Loop Apps בטלפון או בטאבלט. באפליקציה מוצגת רשימת האפליקציות במכשיר שאפשר להפעיל באמצעות לולאות משחק. אם אפליקציית המשחקים לא מופיעה כאן, צריך לוודא שמסנן Intent תואם לזה שמתואר בשלב הראשון של הקטע 'לפני שמתחילים'.
- בוחרים את אפליקציית המשחקים ואז את מספר הלולאות שרוצים להפעיל. הערה: בשלב הזה אפשר לבחור להפעיל קבוצת משנה של לולאות במקום רק לולאה אחת. מידע נוסף על הפעלת כמה לולאות בו-זמנית זמין במאמר בנושא תכונות אופציונליות.
- לוחצים על הפעלת הבדיקה. הבדיקה תתחיל לפעול באופן מיידי.
ריצה בTest Lab
אפשר להריץ בדיקה של Game Loop ב-Test Lab באמצעות מסוף Firebase או ה-CLI של gcloud. לפני שמתחילים, אם עדיין לא עשיתם זאת, פותחים את מסוף Firebase ויוצרים פרויקט.
שימוש במסוף Firebase
- בחלונית הימנית של Firebaseמסוף, לוחצים על Test Lab.
- לוחצים על Run Your First Test (הפעלת הבדיקה הראשונה) או על Run a Test (הפעלת בדיקה) אם כבר הפעלתם בדיקה בפרויקט.
- בוחרים באפשרות Game Loop כסוג הבדיקה ולוחצים על המשך.
- לוחצים על Browse (עיון) ואז עוברים לקובץ
.apkשל האפליקציה. הערה: בשלב הזה אפשר לבחור להפעיל קבוצת משנה של לולאות במקום רק לולאה אחת. מידע נוסף על הפעלת כמה לולאות בו-זמנית זמין במאמר בנושא תכונות אופציונליות. - לוחצים על המשך.
- בוחרים את המכשירים הפיזיים שרוצים להשתמש בהם כדי לבדוק את האפליקציה.
- לוחצים על התחלת הבדיקות.
מידע נוסף על תחילת העבודה עם מסוף Firebase זמין במאמר איך מתחילים לבדוק באמצעות מסוף Firebase.
שימוש בשורת הפקודה (CLI) של gcloud
אם עוד לא עשיתם זאת, מורידים ומתקינים את Google Cloud SDK.
נכנסים ל-CLI של gcloud באמצעות חשבון Google:
gcloud auth loginמגדירים את פרויקט Firebase ב-gcloud, כאשר
PROJECT_IDהוא מזהה פרויקט Firebase: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
למידע נוסף על תחילת העבודה עם ה-CLI של gcloud, אפשר לעיין במאמר תחילת בדיקה משורת הפקודה של gcloud.
תכונות אופציונליות
Test Lab מציע כמה תכונות אופציונליות שמאפשרות לכם להתאים אישית את הבדיקות, כולל האפשרות לכתוב נתוני פלט, תמיכה בכמה לולאות משחק ותוויות ללולאות קשורות.
כתיבת נתוני פלט
במהלך בדיקת לולאת המשחק, אפשר לכתוב את הפלט לקובץ שצוין בשיטה launchIntent.getData(). אחרי שמריצים בדיקה, אפשר לגשת לנתוני הפלט האלה בקטע Test Lab במסוף Firebase (ראו דוגמה לקובץ פלט של בדיקת game loop).
Test Lab פועלת לפי השיטות המומלצות לשיתוף קובץ בין אפליקציות שמתוארות במאמר שיתוף קובץ.
בשיטה onCreate() של הפעילות, שבה נמצאת הכוונה, אפשר לבדוק את קובץ פלט הנתונים על ידי הרצת הקוד הבא:
Kotlin
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
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); }
דוגמה לקובץ פלט
אפשר להשתמש בקובצי נתוני הפלט (בפורמט כמו בדוגמה שלמטה) כדי להציג את תוצאות הבדיקה של לולאת המשחק בקטע Test Lab במסוף Firebase.
באזורים שמסומנים ב-/.../ אפשר להוסיף שדות בהתאמה אישית שנדרשים לכם, כל עוד הם לא מתנגשים עם השמות של שדות אחרים שמשמשים בקובץ הזה:
{
"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
}
מספר game loops
יכול להיות שיהיה לכם שימושי להריץ כמה לולאות משחק באפליקציה. לולאה היא ריצה מלאה של אפליקציית המשחק מההתחלה ועד הסוף. לדוגמה, אם יש כמה רמות במשחק, יכול להיות שתרצו להגדיר לולאת משחק אחת להפעלת כל רמה במקום לולאה אחת שחוזרת על עצמה בכל הרמות. כך, אם האפליקציה קורסת ברמה 32, אפשר להפעיל ישירות את לולאת המשחק הזו כדי לשחזר את הקריסה ולבדוק תיקוני באגים.
כדי לאפשר לאפליקציה להריץ כמה לולאות בו-זמנית:
אם אתם מריצים בדיקה באמצעות Test Loop Manager:
מוסיפים את השורה הבאה למניפסט של האפליקציה, בתוך הרכיב
<application>:<meta-data android:name="com.google.test.loops" android:value="5" />
ה-intent להפעלת הלולאה מכיל את הלולאה הממוקדת כפרמטר מסוג integer. בשדה
android:valueאפשר לציין מספר שלם מ-1 עד 1024 (המספר המקסימלי של לולאות שמותרות לבדיקה אחת). הערה: האינדקס של לולאות מתחיל מ-1 ולא מ-0.באפליקציה Test Loop Manager, מופיע מסך בחירה שמאפשר לבחור אילו לולאות רוצים להריץ. אם בוחרים כמה לולאות, כל לולאה מופעלת ברצף אחרי שהלולאה הקודמת מסתיימת.
אם אתם מריצים בדיקה באמצעות מסוף Firebase, מזינים רשימה או טווח של מספרי לולאות בשדה תרחישים.
אם אתם מריצים בדיקה באמצעות ה-CLI של gcloud, ציינו רשימה של מספרי לולאות באמצעות הדגל
--scenario-numbers. לדוגמה,--scenario-numbers=1,3,5מפעיל את לולאות 1, 3 ו-5.אם אתם כותבים C++ ורוצים לשנות את ההתנהגות של הלולאה, צריך להעביר את התוספת הבאה לקוד C++ המקורי:
Kotlin
val launchIntent = intent val scenario = launchIntent.getIntExtra("scenario", 0)
Java
Intent launchIntent = getIntent(); int scenario = launchIntent.getIntExtra("scenario", 0);
עכשיו אפשר לשנות את ההתנהגות של הלולאה על סמך הערך שמתקבל
int
מתן תוויות ל-game loops
כשמתייגים את לולאות המשחק בתווית תרחיש אחת או יותר, אתם וצוות בקרת האיכות יכולים להפעיל בקלות קבוצה של לולאות משחק קשורות (למשל, 'כל לולאות המשחק של התאימות') ולבדוק אותן במטריצה אחת. אתם יכולים ליצור תוויות משלכם או להשתמש בתוויות המוגדרות מראש שמוצעות על ידי Test Lab:
-
com.google.test.loops.player_experience: לולאות For שמשמשות לשחזור חוויית משתמש אמיתית בזמן המשחק. המטרה של בדיקות עם הלולאות האלה היא למצוא בעיות שמשתמש אמיתי ייתקל בהן בזמן המשחק. -
com.google.test.loops.gpu_compatibility: לולאות for שמשמשות לבדיקת בעיות שקשורות ל-GPU. המטרה של בדיקות עם לולאות כאלה היא להריץ קוד GPU שלא יכול להיות שיפעל בצורה תקינה בסביבת הייצור, כדי לחשוף בעיות בחומרה ובדרייברים. -
com.google.test.loops.compatibility: לולאות for שמשמשות לבדיקה של מגוון רחב של בעיות תאימות, כולל בעיות קלט/פלט ובעיות OpenSSL. -
com.google.test.loops.performance: לולאות for שמשמשות לבדיקת הביצועים של המכשיר. לדוגמה, יכול להיות שמשחק יפעל בהגדרות הגרפיקה המורכבות ביותר כדי לבדוק את ההתנהגות של מכשיר חדש.
כדי לאפשר לאפליקציה להריץ לולאות עם אותה תווית:
אם אתם מריצים בדיקה באמצעות Test Loop Manager:
במניפסט של האפליקציה, מוסיפים את שורת המטא-נתונים הבאה ומחליפים את 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.באפליקציה Test Loop Manager, מזינים תווית אחת או יותר בשדה Labels (תוויות).
אם אתם מריצים בדיקה באמצעות מסוף Firebase, מזינים תווית אחת או יותר בשדה Labels.
אם מריצים בדיקה באמצעות ה-CLI של gcloud, מציינים תווית תרחיש אחת או יותר באמצעות הדגל
--scenario-labels(לדוגמה,--scenario-labels=performance,gpu).
תמיכה ברישוי לשימוש באפליקציות
Test Lab תומך באפליקציות שמשתמשות בשירות App Licensing שמוצע על ידי Google Play. כדי לבדוק את הרישוי בהצלחה כשבודקים את האפליקציה באמצעות Test Lab, צריך לפרסם את האפליקציה בערוץ הייצור בחנות Play. כדי לבדוק את האפליקציה בערוץ אלפא או בטא באמצעות Test Lab, צריך להסיר את בדיקת הרישיון לפני העלאת האפליקציה אל Test Lab.
בעיות מוכרות
הבעיות הבאות מוכרות בבדיקות של לולאות משחק ב-Test Lab:
- חלק מהקריסות לא תומכות ב-backtrace. לדוגמה, יכול להיות שבחלק מהגרסאות לא יופיע הפלט של התהליך
debuggerdבאמצעותprctl(PR_SET_DUMPABLE, 0). מידע נוסף זמין במאמרdebuggerd. - כרגע אין תמיכה ברמת API 19 בגלל שגיאות בהרשאות לקבצים.