การทดสอบเกมแบบอัตโนมัติอาจทำได้ยากเมื่อแอปเล่นเกมสร้างขึ้นบนเฟรมเวิร์ก UI ที่ต่างกัน การทดสอบ Game Loop ช่วยให้คุณผสานรวมการทดสอบแบบเนทีฟกับ Test Lab และเรียกใช้การทดสอบบนอุปกรณ์ที่เลือกได้อย่างง่ายดาย การทดสอบ Game Loop จะทำการทดสอบผ่านแอปเล่นเกมของคุณขณะจำลองการดําเนินการของผู้เล่นจริง คู่มือนี้จะแสดงวิธีทำการทดสอบ Game Loop จากนั้นดูและจัดการผลการทดสอบในคอนโซล Firebase
คุณสามารถใช้การทดสอบที่มี Loop เดียวหรือหลาย Loop ทั้งนี้ขึ้นอยู่กับเครื่องมือสร้างเกม ลูปคือการทดสอบแอปเล่นเกมของคุณทั้งบางส่วนหรือทั้งหมด ลูปเกมมีไว้เพื่อดำเนินการต่อไปนี้
- เรียกใช้ด่านของเกมในลักษณะเดียวกับที่ผู้ใช้ปลายทางจะเล่น คุณสามารถเขียนสคริปต์การป้อนข้อมูลของผู้ใช้ ปล่อยให้ผู้ใช้ไม่มีความเคลื่อนไหว หรือแทนที่ผู้ใช้ด้วย AI ก็ได้หากมีความเหมาะสมในเกมของคุณ (เช่น สมมติว่าคุณมีแอปเล่นเกมรถแข่งและใช้งาน AI อยู่แล้ว คุณสามารถใช้ AI เป็นตัวควบคุมที่รับผิดชอบอินพุตของผู้ใช้ได้อย่างง่ายดาย
- เรียกใช้เกมที่การตั้งค่าคุณภาพสูงสุดเพื่อดูว่าอุปกรณ์รองรับหรือไม่
- ทำการทดสอบทางเทคนิค (คอมไพล์ตัวปรับแสงเงาหลายๆ ตัว เรียกใช้ เรียกใช้ ตรวจสอบว่าเอาต์พุตเป็นไปตามที่คาดไว้ ฯลฯ)
คุณสามารถทำการทดสอบ Game Loop บนอุปกรณ์ทดสอบเครื่องเดียว ชุดอุปกรณ์ทดสอบ หรือใน Test Lab อย่างไรก็ตาม เราไม่แนะนำให้ทำการทดสอบ Game Loop บนอุปกรณ์เสมือนเนื่องจากมีอัตราเฟรมกราฟิกต่ำกว่าอุปกรณ์จริง
ก่อนเริ่มต้น
หากต้องการใช้การทดสอบ คุณต้องกําหนดค่าแอปสําหรับการทดสอบ Game Loop ก่อน
ในไฟล์ Manifest ของแอป ให้เพิ่มตัวกรอง Intent ใหม่ลงใน activity ดังนี้
<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+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 }
ซึ่งจะช่วยให้กิจกรรมตรวจสอบ Intent ที่เปิดใช้งานได้ นอกจากนี้ คุณยังเพิ่มโค้ดนี้ในภายหลังได้หากต้องการ (เช่น หลังจากโหลดเครื่องมือเล่นเกมครั้งแรก)
แนะนํา: เมื่อสิ้นสุดการทดสอบ ให้เพิ่มข้อมูลต่อไปนี้
Kotlin+KTX
yourActivity.finish()
Java
yourActivity.finish();
การดำเนินการนี้จะปิดแอปของคุณเมื่อการทดสอบ Game Loop เสร็จสมบูรณ์ การทดสอบอาศัยเฟรมเวิร์ก UI ของแอปเพื่อเริ่มลูปถัดไป และการปิดแอปจะบอกให้ระบบทราบว่าการทดสอบเสร็จสิ้นแล้ว
สร้างและทำการทดสอบ Game Loop
หลังจากกำหนดค่าแอปสำหรับการทดสอบ Game Loop แล้ว คุณสามารถสร้างการทดสอบและเรียกใช้ในแอปเล่นเกมได้ทันที โดยเลือกที่จะทำการทดสอบใน Test Lab โดยใช้คอนโซล Firebase หรือ gcloud command line interface (CLI) หรือในอุปกรณ์เครื่องที่ใช้อยู่โดยใช้ Test Loop Manager ก็ได้
เรียกใช้ในอุปกรณ์ภายใน
Test Loop Manager ของ Test Lab เป็นแอปโอเพนซอร์สที่ช่วยให้คุณผสานรวมการทดสอบ Game Loop และเรียกใช้การทดสอบเหล่านั้นในอุปกรณ์ภายในของคุณ นอกจากนี้ยังช่วยให้ทีมตรวจสอบคุณภาพสามารถเรียกใช้ลูปเกมเดียวกันในอุปกรณ์ของตนได้อีกด้วย
วิธีทำการทดสอบในอุปกรณ์เครื่องที่ใช้อยู่โดยใช้เครื่องมือจัดการ Test Loop
- ดาวน์โหลด Test Loop Manager ในโทรศัพท์หรือแท็บเล็ต แล้วติดตั้งโดยเรียกใช้คำสั่งต่อไปนี้
adb install testloopmanager.apk
- เปิดแอปแอป Test Loop ในโทรศัพท์หรือแท็บเล็ต แอปจะแสดงรายการแอปในอุปกรณ์ที่ทำงานกับลูปเกมได้ หากไม่เห็นแอปเกมที่นี่ ให้ตรวจสอบว่าตัวกรอง Intent ตรงกับรายการที่อธิบายไว้ในขั้นตอนแรกของส่วนก่อนเริ่มต้น
- เลือกแอปเล่นเกม แล้วเลือกจำนวนรอบที่ต้องการเรียกใช้ หมายเหตุ: ในขั้นตอนนี้ คุณสามารถเลือกเรียกใช้ชุดย่อยของลูปแทนที่จะเรียกใช้เพียงลูปเดียว ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้ลูปหลายรายการพร้อมกันที่ฟีเจอร์เสริม
- คลิกเรียกใช้การทดสอบ การทดสอบจะเริ่มทํางานทันที
ทำงานใน Test Lab
คุณสามารถทำการทดสอบ Game Loop ใน Test Lab โดยใช้คอนโซล Firebase หรือ gcloud CLI ก่อนเริ่มต้น ให้เปิดคอนโซล Firebase และสร้างโปรเจ็กต์ หากยังไม่ได้ดำเนินการ
ใช้คอนโซล Firebase
- ในคอนโซล Firebase ให้คลิก Test Lab จากแผงด้านซ้าย
- คลิกเรียกใช้การทดสอบครั้งแรก (หรือเรียกใช้การทดสอบหากโปรเจ็กต์เคยเรียกใช้การทดสอบแล้ว)
- เลือก Game Loop เป็นประเภทการทดสอบ แล้วคลิกต่อไป
- คลิกเรียกดู แล้วเรียกดูไฟล์
.apk
ของแอป หมายเหตุ: ในขั้นตอนนี้ คุณเลือกเรียกใช้การวนซ้ำชุดย่อยแทนการวนซ้ำเพียงรายการเดียวได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้ลูปหลายรายการพร้อมกันได้ที่ฟีเจอร์ที่ไม่บังคับ - คลิกต่อไป
- เลือกอุปกรณ์จริงที่จะใช้ทดสอบแอป
- คลิกเริ่มการทดสอบ
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มต้นใช้งานคอนโซล Firebase ได้ที่เริ่มการทดสอบด้วยคอนโซล Firebase
ใช้บรรทัดคำสั่ง gcloud (CLI)
ดาวน์โหลดและติดตั้ง Google Cloud SDK หากยังไม่ได้ดำเนินการ
ลงชื่อเข้าใช้ gcloud CLI โดยใช้บัญชี 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
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มต้นใช้งาน gcloud CLI ได้ที่เริ่มทดสอบจากบรรทัดคำสั่ง gcloud
ฟีเจอร์เสริม
Test Lab มีฟีเจอร์เสริมหลายอย่างที่ช่วยให้คุณปรับแต่งการทดสอบเพิ่มเติมได้ ซึ่งรวมถึงความสามารถในการเขียนข้อมูลเอาต์พุต รองรับเกมลูปหลายรายการ และป้ายกำกับสำหรับลูปที่เกี่ยวข้อง
เขียนข้อมูลเอาต์พุต
การทดสอบ Game Loop สามารถเขียนเอาต์พุตไปยังไฟล์ที่ระบุในเมธอด launchIntent.getData()
หลังจากทำการทดสอบแล้ว คุณจะเข้าถึงข้อมูลเอาต์พุตนี้ได้ในส่วน Test Lab ของคอนโซล Firebase (ดูตัวอย่างไฟล์เอาต์พุตการทดสอบรอบเกม)
Test Lab ปฏิบัติตามแนวทางปฏิบัติแนะนำสำหรับการแชร์ไฟล์ระหว่างแอปตามที่อธิบายไว้ในหัวข้อการแชร์ไฟล์
ในเมธอด onCreate()
ของกิจกรรมซึ่งมี Intent อยู่ คุณสามารถตรวจสอบไฟล์เอาต์พุตข้อมูลได้โดยเรียกใช้โค้ดต่อไปนี้
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); }
ตัวอย่างไฟล์เอาต์พุต
คุณสามารถใช้ไฟล์ข้อมูลเอาต์พุต (จัดรูปแบบตามตัวอย่างด้านล่าง) เพื่อแสดงผลการทดสอบลูปเกมได้ในส่วน 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 หลายรายการในแอปมีประโยชน์ โดย Loop คือการดำเนินการแอปเกมตั้งแต่ต้นจนจบอย่างสมบูรณ์ เช่น หากเกมมีหลายด่าน คุณอาจต้องการใช้ลูปเกม 1 รายการเพื่อเปิดแต่ละด่านแทนที่จะใช้ลูป 1 รายการที่วนซ้ำผ่านด่านทั้งหมด ด้วยวิธีนี้ หากแอปขัดข้องในระดับ 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+KTX
val launchIntent = intent val scenario = launchIntent.getIntExtra("scenario", 0)
Java
Intent launchIntent = getIntent(); int scenario = launchIntent.getIntExtra("scenario", 0);
ตอนนี้คุณสามารถเปลี่ยนลักษณะการทํางานของลูปตาม
int
ค่าที่ได้
ติดป้ายกำกับ Game Loop
เมื่อติดป้ายกำกับ Game Loop ด้วยป้ายกำกับสถานการณ์อย่างน้อย 1 รายการ คุณและทีม QA สามารถเปิดชุด Game Loop ที่เกี่ยวข้องได้โดยง่าย (เช่น "all compatibility game loops") และทดสอบในเมทริกซ์เดียว คุณสามารถสร้างป้ายกำกับของคุณเองหรือใช้ป้ายกำกับที่กำหนดไว้ล่วงหน้าซึ่ง 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 ให้ป้อนป้ายกำกับอย่างน้อย 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 มีปัญหาที่ทราบดังต่อไปนี้
- ข้อขัดข้องบางรายการไม่รองรับ Backtrace เช่น บิลด์รุ่นบางเวอร์ชันอาจระงับเอาต์พุตของกระบวนการ
debuggerd
โดยใช้prctl(PR_SET_DUMPABLE, 0)
ดูข้อมูลเพิ่มเติมได้ที่debuggerd
- ขณะนี้ระบบยังไม่รองรับ API ระดับ 19 เนื่องจากข้อผิดพลาดเกี่ยวกับสิทธิ์ของไฟล์