การทดสอบเกมอัตโนมัติอาจทำได้ยากเมื่อแอปเกมสร้างขึ้นบนเฟรมเวิร์ก UI ที่แตกต่างกัน การทดสอบ Game Loop ช่วยให้คุณผสานรวมการทดสอบดั้งเดิมกับ Test Lab และเรียกใช้การทดสอบเหล่านั้นในอุปกรณ์ที่คุณเลือกได้อย่างง่ายดาย การทดสอบ Game Loop จะเรียกใช้การทดสอบผ่านแอปเกมของคุณขณะจำลองการกระทำของผู้เล่นจริง คู่มือนี้จะแสดงวิธีเรียกใช้การทดสอบ Game Loop จากนั้นดูและจัดการผลการทดสอบ ในคอนโซล Firebase
คุณสามารถใช้การทดสอบที่มีลูปเดียวหรือหลายลูปได้ ทั้งนี้ขึ้นอยู่กับเกมเอนจินของคุณ ลูปคือการเรียกใช้การทดสอบในแอปเกมของคุณแบบเต็มหรือบางส่วน โดยคุณสามารถใช้ Game Loop เพื่อทำสิ่งต่อไปนี้ได้
- เรียกใช้ระดับหนึ่งของเกมในลักษณะเดียวกับที่ผู้ใช้ปลายทางจะเล่น คุณสามารถเขียนสคริปต์อินพุตของผู้ใช้ ปล่อยให้ผู้ใช้ไม่มีการใช้งาน หรือแทนที่ผู้ใช้ด้วย AI หากเหมาะสมกับเกมของคุณ (เช่น สมมติว่าคุณมีแอปเกมแข่งรถและได้ติดตั้งใช้งาน AI แล้ว) คุณสามารถมอบหมายให้ AI เป็นผู้ขับรถแทนอินพุตของผู้ใช้ได้อย่างง่ายดาย)
- เรียกใช้เกมด้วยการตั้งค่าคุณภาพสูงสุดเพื่อดูว่าอุปกรณ์รองรับหรือไม่
- เรียกใช้การทดสอบทางเทคนิค (คอมไพล์เชเดอร์หลายรายการ เรียกใช้เชเดอร์เหล่านั้น ตรวจสอบว่าเอาต์พุตเป็นไปตามที่คาดไว้ ฯลฯ)
คุณสามารถเรียกใช้การทดสอบ Game Loop ในอุปกรณ์ทดสอบเครื่องเดียว อุปกรณ์ทดสอบหลายเครื่อง หรือ ใน Test Lab อย่างไรก็ตาม เราไม่แนะนำให้เรียกใช้การทดสอบ Game Loop ในอุปกรณ์เสมือนเนื่องจากมีอัตราเฟรมกราฟิกต่ำกว่าอุปกรณ์จริง
ก่อนเริ่มต้น
หากต้องการใช้การทดสอบ คุณต้องกำหนดค่าแอปสำหรับการทดสอบ Game Loop ก่อน
ในไฟล์ Manifest ของแอป ให้เพิ่มตัวกรอง 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 เปิดเกมของคุณได้โดยการทริกเกอร์ด้วย Intent ที่เฉพาะเจาะจง
เพิ่มโค้ดต่อไปนี้ในโค้ดของคุณ (เราแนะนำให้เพิ่มภายในประกาศเมธอด
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 }
ซึ่งจะช่วยให้กิจกรรมตรวจสอบ Intent ที่เปิดกิจกรรมได้ นอกจากนี้ คุณยังเพิ่มโค้ดนี้ในภายหลังได้หากต้องการ (เช่น หลังจากโหลดเอนจินเกมในตอนแรก)
แนะนำ: เพิ่มโค้ดต่อไปนี้เมื่อสิ้นสุดการทดสอบ
Kotlin
yourActivity.finish()
Java
yourActivity.finish();
ซึ่งจะปิดแอปเมื่อการทดสอบ Game Loop เสร็จสมบูรณ์ การทดสอบจะอาศัยเฟรมเวิร์ก UI ของแอปเพื่อเริ่มลูปถัดไป และการปิดแอปจะบอกให้เฟรมเวิร์ก UI ทราบว่าการทดสอบเสร็จสิ้นแล้ว
สร้างและเรียกใช้การทดสอบ Game Loop
หลังจากกำหนดค่าแอปสำหรับการทดสอบ Game Loop แล้ว คุณจะสร้างการทดสอบและดำเนินการทดสอบในแอปเกมได้ทันที โดยคุณสามารถเลือกเรียกใช้การทดสอบใน Test Lab โดยใช้Firebase คอนโซล หรืออินเทอร์เฟซบรรทัดคำสั่ง gcloud (CLI) หรือในอุปกรณ์ในเครื่องโดยใช้ Test Loop Manager
เรียกใช้ในอุปกรณ์ในเครื่อง
Test Lab**Test Loop Manager** ของ Test Lab's เป็นแอปโอเพนซอร์สที่จะช่วยคุณ ผสานรวมการทดสอบ Game Loop และเรียกใช้การทดสอบเหล่านั้นในอุปกรณ์ในเครื่อง นอกจากนี้ยังช่วยให้ทีมประกันคุณภาพเรียกใช้ Game Loop เดียวกันในอุปกรณ์ของทีมได้ด้วย
วิธีเรียกใช้การทดสอบในอุปกรณ์ในเครื่องโดยใช้ Test Loop Manager
- ดาวน์โหลด Test Loop Manager
ในโทรศัพท์หรือแท็บเล็ต และติดตั้งโดยเรียกใช้คำสั่งต่อไปนี้
adb install testloopmanager.apk
- เปิดแอป Test Loop Apps ในโทรศัพท์หรือแท็บเล็ต แอปจะแสดงรายการแอปในอุปกรณ์ที่เรียกใช้ด้วย Game Loop ได้ หากไม่เห็นแอปเกมที่นี่ ให้ตรวจสอบว่า ตัวกรอง Intent ตรงกับตัวกรองที่อธิบายไว้ในขั้นตอนแรกของ ส่วนก่อนเริ่มต้น
- เลือกแอปเกม จากนั้นเลือกจำนวนลูปที่ต้องการเรียกใช้ หมายเหตุ: ในขั้นตอนนี้ คุณสามารถเลือกเรียกใช้ลูปบางส่วนแทนที่จะเรียกใช้เพียงลูปเดียว ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้หลายลูปพร้อมกันได้ที่ ฟีเจอร์เสริม
- คลิกเรียกใช้การทดสอบ การทดสอบจะเริ่มทำงานทันที
เรียกใช้ใน Test Lab
คุณสามารถเรียกใช้การทดสอบ Game Loop ใน Test Lab โดยใช้ Firebase คอนโซล หรือ gcloud CLI ก่อนเริ่มต้น ให้เปิด Firebaseคอนโซลและสร้างโปรเจ็กต์ หากยังไม่ได้ดำเนินการ
ใช้คอนโซล Firebase
- ในคอนโซล Firebase ให้คลิก Test Lab จากแผงด้านซ้าย
- คลิกเรียกใช้การทดสอบครั้งแรก (หรือเรียกใช้การทดสอบ หากโปรเจ็กต์เคยเรียกใช้การทดสอบแล้ว)
- เลือก Game Loop เป็นประเภทการทดสอบ แล้วคลิกดำเนินการต่อ
- คลิกเรียกดู แล้วเรียกดูไฟล์
.apkของแอป หมายเหตุ: ในขั้นตอนนี้ คุณสามารถเลือกเรียกใช้ลูปบางส่วนแทนที่จะเรียกใช้เพียงลูปเดียว ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้หลายลูปพร้อมกันได้ที่ ฟีเจอร์เสริม - คลิกดำเนินการต่อ
- เลือกอุปกรณ์จริงที่จะใช้ทดสอบแอป
- คลิกเริ่มการทดสอบ
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มต้นใช้งานคอนโซล Firebase ได้ที่ หัวข้อเริ่มการทดสอบด้วยคอนโซล Firebase.
ใช้บรรทัดคำสั่ง (CLI) ของ gcloud
ดาวน์โหลดและติดตั้ง Google Cloud SDK
ลงชื่อเข้าใช้ gcloud CLI ด้วยบัญชี Google โดยใช้คำสั่งต่อไปนี้
gcloud auth loginตั้งค่าโปรเจ็กต์ Firebase ใน gcloud โดยที่
PROJECT_IDคือรหัสโปรเจ็กต์ Firebasegcloud 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 มีฟีเจอร์เสริมหลายอย่างที่ช่วยให้คุณปรับแต่งการทดสอบ เพิ่มเติมได้ ซึ่งรวมถึงความสามารถในการเขียนข้อมูลเอาต์พุต การรองรับ Game Loop หลายรายการ และป้ายกำกับสำหรับลูปที่เกี่ยวข้อง
เขียนข้อมูลเอาต์พุต
การทดสอบ Game Loop สามารถเขียนเอาต์พุตลงในไฟล์ที่ระบุไว้ในเมธอด launchIntent.getData() หลังจากเรียกใช้การทดสอบแล้ว คุณจะเข้าถึงข้อมูลเอาต์พุตนี้ได้ในส่วน Test Lab ของคอนโซล Firebase (ดู
ตัวอย่างไฟล์เอาต์พุตการทดสอบ Game Loop)
Test Lab ปฏิบัติตามแนวทางปฏิบัติแนะนำสำหรับการแชร์ไฟล์ระหว่างแอปที่อธิบายไว้ใน
หัวข้อการแชร์ไฟล์
ในเมธอด onCreate() ของกิจกรรม ซึ่งเป็นตำแหน่งที่ Intent อยู่ คุณสามารถตรวจสอบไฟล์เอาต์พุตข้อมูลได้โดยเรียกใช้โค้ดต่อไปนี้
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); }
ตัวอย่างไฟล์เอาต์พุต
คุณสามารถใช้ไฟล์ข้อมูลเอาต์พุต (จัดรูปแบบเหมือนตัวอย่างด้านล่าง) เพื่อแสดงผลการทดสอบ Game
Loop ในส่วน 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 Loop หลายรายการ
คุณอาจพบว่าการเรียกใช้ Game Loop หลายรายการในแอปมีประโยชน์ โดยลูปคือการเรียกใช้แอปเกมของคุณแบบเต็มตั้งแต่ต้นจนจบ ตัวอย่างเช่น หากเกมมีหลายระดับ คุณอาจต้องการให้มี Game Loop 1 รายการเพื่อเปิดแต่ละระดับแทนที่จะมีลูปเดียวที่วนซ้ำผ่านทุกระดับ วิธีนี้จะช่วยให้คุณเปิด Game Loop นั้นได้โดยตรงเพื่อจำลองข้อขัดข้องและทดสอบการแก้ไขข้อบกพร่อง หากแอปขัดข้องในระดับ 32
วิธีเปิดใช้แอปให้เรียกใช้หลายลูปพร้อมกัน
หากคุณเรียกใช้การทดสอบด้วย Test Loop Manager ให้ทำดังนี้
เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ Manifest ของแอปภายในองค์ประกอบ
<application><meta-data android:name="com.google.test.loops" android:value="5" />
Intent ในการเปิดนี้มีลูปเป้าหมายเป็นพารามิเตอร์จำนวนเต็ม ในช่อง
android:valueคุณสามารถระบุจำนวนเต็มตั้งแต่ 1 ถึง 1024 (จำนวนลูปสูงสุดที่อนุญาตสำหรับการทดสอบเดียว) โปรดทราบว่าลูปจะมีการจัดทำดัชนีโดยเริ่มจาก 1 ไม่ใช่ 0ในแอป Test Loop Manager หน้าจอการเลือกจะปรากฏขึ้น ซึ่งช่วยให้คุณเลือกลูปที่ต้องการเรียกใช้ได้ หากเลือกลูปหลายรายการ ระบบจะเปิดใช้แต่ละลูปตามลำดับหลังจากลูปก่อนหน้าเสร็จสมบูรณ์
หากคุณเรียกใช้การทดสอบด้วยคอนโซล Firebase ให้ป้อนรายการหรือ ช่วงของหมายเลขลูปในช่องสถานการณ์
หากคุณเรียกใช้การทดสอบด้วย gcloud CLI ให้ระบุรายการหมายเลขลูปโดยใช้แฟล็ก
--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 Loop
เมื่อติดป้ายกำกับสถานการณ์อย่างน้อย 1 รายการให้กับ Game Loop คุณและทีม QA จะเปิดใช้ชุด Game Loop ที่เกี่ยวข้อง (เช่น "Game Loop ทั้งหมดที่เข้ากันได้") และทดสอบในเมทริกซ์เดียวได้อย่างง่ายดาย คุณสามารถสร้างป้ายกำกับของคุณเองหรือ ใช้ป้ายกำกับที่กำหนดไว้ล่วงหน้าซึ่ง Test Lab มีให้
com.google.test.loops.player_experience: สำหรับลูปที่ใช้เพื่อจำลองประสบการณ์ของผู้ใช้จริงเมื่อเล่นเกม เป้าหมายของการทดสอบด้วยลูปเหล่านี้คือการค้นหาปัญหาที่ผู้ใช้จริงจะพบขณะเล่นเกมcom.google.test.loops.gpu_compatibility: สำหรับลูปที่ใช้เพื่อทดสอบปัญหาที่เกี่ยวข้องกับ GPU เป้าหมายของการทดสอบด้วยลูปเหล่านี้คือการเรียกใช้โค้ด GPU ที่อาจทำงานไม่ถูกต้องในสภาพแวดล้อมจริง เพื่อเปิดเผยปัญหาเกี่ยวกับฮาร์ดแวร์และไดรเวอร์com.google.test.loops.compatibility: สำหรับลูปที่ใช้เพื่อทดสอบปัญหาความเข้ากันได้ที่หลากหลาย รวมถึงปัญหา I/O และปัญหา OpenSSLcom.google.test.loops.performance: สำหรับลูปที่ใช้เพื่อทดสอบประสิทธิภาพของอุปกรณ์ ตัวอย่างเช่น เกมอาจทำงานด้วยการตั้งค่ากราฟิกที่ซับซ้อนที่สุดเพื่อดูว่าอุปกรณ์ใหม่ทำงานอย่างไร
วิธีเปิดใช้แอปให้เรียกใช้ลูปที่มีป้ายกำกับเดียวกัน
หากคุณเรียกใช้การทดสอบด้วย Test Loop Manager ให้ทำดังนี้
เพิ่มบรรทัดข้อมูลเมตาต่อไปนี้ในไฟล์ Manifest ของแอป และแทนที่ 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 ให้ป้อนป้ายกำกับอย่างน้อย 1 รายการในช่องป้ายกำกับ
หากคุณเรียกใช้การทดสอบด้วยคอนโซล Firebase ให้ป้อน ป้ายกำกับอย่างน้อย 1 รายการในช่องป้ายกำกับ
หากคุณเรียกใช้การทดสอบด้วย gcloud CLI ให้ระบุป้ายกำกับสถานการณ์อย่างน้อย 1 รายการโดยใช้แฟล็ก
--scenario-labels(เช่น--scenario-labels=performance,gpu)
การรองรับการอนุญาตให้ใช้สิทธิแอป
Test Lab รองรับแอปที่ใช้บริการ การอนุญาตให้ใช้สิทธิแอป ที่ Google Play มีให้ หากต้องการตรวจสอบการอนุญาตให้ใช้สิทธิเมื่อทดสอบ แอปด้วย Test Lab ให้สำเร็จ คุณต้องเผยแพร่แอปไปยังช่องทางเวอร์ชันที่ใช้งานจริง ใน Play Store หากต้องการทดสอบแอปในช่องทางอัลฟ่าหรือเบต้าโดยใช้ Test Lab ให้นำการตรวจสอบการอนุญาตให้ใช้สิทธิออกก่อนอัปโหลดแอปไปยัง Test Lab
ปัญหาที่ทราบ
การทดสอบ Game Loop ใน Test Lab มีปัญหาที่ทราบดังต่อไปนี้
- ข้อขัดข้องบางอย่างไม่รองรับการติดตามการเรียกใช้ฟังก์ชันย้อนกลับ ตัวอย่างเช่น บิลด์ที่เผยแพร่บางรายการอาจระงับเอาต์พุตของกระบวนการ
debuggerdโดยใช้prctl(PR_SET_DUMPABLE, 0)ดูข้อมูลเพิ่มเติมได้ที่debuggerd - ปัจจุบันระบบยังไม่รองรับ API ระดับ 19 เนื่องจากข้อผิดพลาดเกี่ยวกับสิทธิ์ของไฟล์