เริ่มต้นใช้งานการทดสอบ Game Loop

การทำให้การทดสอบเกมเป็นไปโดยอัตโนมัติอาจเป็นเรื่องยากเมื่อแอปเกมสร้างขึ้นบนเฟรมเวิร์ก UI ที่แตกต่างกัน การทดสอบ Game Loop ให้คุณผสานรวมการทดสอบแบบเนทีฟกับ Test Lab และทำการทดสอบบนอุปกรณ์ที่คุณเลือกได้อย่างง่ายดาย การทดสอบ Game Loop ทำการทดสอบ ผ่านแอปเกมของคุณ ขณะจำลองการกระทำของผู้เล่นจริง คู่มือนี้จะแสดงวิธีทำการทดสอบ Game Loop จากนั้นดูและจัดการผลการทดสอบได้ในคอนโซล Firebase

คุณสามารถใช้การทดสอบแบบลูปเดียวหรือหลายลูป ทั้งนี้ขึ้นอยู่กับเครื่องมือเกมของคุณ ลูปคือการทดสอบซ้ำทั้งหมดหรือบางส่วนในแอปเกม คุณสามารถใช้ Game Loop เพื่อทำสิ่งต่อไปนี้

  • เรียกใช้ระดับของเกมแบบเดียวกับที่ผู้ใช้ปลายทางเล่น คุณสามารถเขียนสคริปต์อินพุตของผู้ใช้ ปล่อยให้ผู้ใช้ไม่มีการใช้งาน หรือแทนที่ผู้ใช้ด้วย AI ในเกมของคุณ (เช่น หากคุณมีแอปเกมรถแข่งและมี AI ให้ใช้งานอยู่แล้ว คุณสามารถตั้งให้ไดรเวอร์ AI ควบคุมอินพุตของผู้ใช้ได้อย่างง่ายดาย)
  • เรียกใช้เกมด้วยการตั้งค่าคุณภาพสูงสุดเพื่อดูว่าอุปกรณ์รองรับหรือไม่
  • ทำการทดสอบทางเทคนิค (คอมไพล์ตัวสร้างเงาหลายๆ ตัว เรียกใช้การทดลอง ตรวจสอบว่าผลลัพธ์ที่ได้เป็นไปตามที่คาดไว้ เป็นต้น)

คุณสามารถทำการทดสอบ Game Loop บนอุปกรณ์ทดสอบเครื่องเดียว ชุดอุปกรณ์ทดสอบ หรือทดสอบใน Test Lab ได้ อย่างไรก็ตาม เราไม่แนะนำให้ทำการทดสอบ Game Loop ในอุปกรณ์เสมือน เนื่องจากอุปกรณ์มีอัตราเฟรมกราฟิกต่ำกว่าอุปกรณ์จริง

ก่อนเริ่มต้น

หากต้องการใช้การทดสอบ คุณต้องกำหนดค่าแอปสำหรับการทดสอบ Game Loop ก่อน

  1. ในไฟล์ 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 เปิดเกมขึ้นมาด้วยการทริกเกอร์เกมด้วยความตั้งใจที่เฉพาะเจาะจง

  2. ในโค้ดของคุณ (เราขอแนะนำให้ภายในการประกาศเมธอด 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
    }

    ซึ่งจะช่วยให้กิจกรรมตรวจสอบความตั้งใจที่จะเปิดใช้ นอกจากนี้ คุณยังเพิ่มโค้ดนี้ได้ในภายหลังหากต้องการ (เช่น หลังจากโหลดเครื่องมือเกมเป็นครั้งแรก)

  3. คำแนะนำ: เมื่อทดสอบเสร็จแล้ว ให้เพิ่มสิ่งต่อไปนี้

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    ซึ่งจะเป็นการปิดแอปของคุณเมื่อการทดสอบ Game Loop เสร็จสมบูรณ์ การทดสอบจะใช้เฟรมเวิร์ก UI ของแอปเพื่อเริ่มลูปถัดไป และการปิดแอปจะบอกว่าการทดสอบเสร็จสิ้นแล้ว

สร้างและทำการทดสอบ Game Loop

หลังจากกำหนดค่าแอปสำหรับการทดสอบ Game Loop แล้ว คุณจะสร้างการทดสอบและเรียกใช้ในแอปเกมได้ทันที คุณสามารถเลือกทำการทดสอบใน Test Lab ได้โดยใช้คอนโซล Firebase หรืออินเทอร์เฟซบรรทัดคำสั่ง gcloud (CLI) หรือในอุปกรณ์ภายในโดยใช้ Test Loop

เรียกใช้ในอุปกรณ์ของคุณเอง

Test Loop Manager ของ Test Lab คือแอปโอเพนซอร์สที่ช่วยคุณผสานรวมการทดสอบ Game Loop และเรียกใช้บนอุปกรณ์ของคุณเอง และยังช่วยให้ทีมประกันคุณภาพเรียกใช้ Game Loop เดียวกันได้ในอุปกรณ์ของตน

วิธีทำการทดสอบในอุปกรณ์ภายในโดยใช้ตัวจัดการ Test Loop

  1. ดาวน์โหลดตัวจัดการ Test Loop บนโทรศัพท์หรือแท็บเล็ต แล้วติดตั้งโดยเรียกใช้คำสั่งต่อไปนี้
    adb install testloopmanager.apk
  2. เปิดแอปแอป Test Loop ในโทรศัพท์หรือแท็บเล็ต แอปจะแสดงรายการแอปในอุปกรณ์ที่เรียกใช้ Game Loop ได้ หากไม่เห็นแอปเล่นเกมที่นี่ ให้ตรวจสอบว่าตัวกรอง Intent ตรงกับที่อธิบายไว้ในขั้นตอนแรกของส่วน "ก่อนเริ่มต้น"
  3. เลือกแอปเล่นเกม จากนั้นเลือกจำนวนการวนซ้ำที่ต้องการเรียกใช้ หมายเหตุ: ในขั้นตอนนี้ คุณเลือกเรียกใช้เซ็ตย่อยของการวนซ้ำแทนการเรียกใช้เพียง 1 รอบได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้การวนซ้ำหลายรายการพร้อมกันได้ที่ฟีเจอร์ที่ไม่บังคับ
  4. คลิกเรียกใช้การทดสอบ การทดสอบจะเริ่มทำงานทันที

เรียกใช้ใน Test Lab

คุณทำการทดสอบ Game Loop ใน Test Lab ได้โดยใช้คอนโซล Firebase หรือ gcloud CLI ก่อนเริ่มต้น ให้เปิดคอนโซล Firebase แล้วสร้างโปรเจ็กต์ หากยังไม่ได้เริ่ม

ใช้คอนโซล Firebase

  1. ในคอนโซล Firebase ให้คลิก Test Lab จากแผงด้านซ้าย
  2. คลิกเรียกใช้การทดสอบแรก (หรือเรียกใช้การทดสอบ หากโปรเจ็กต์ได้ทำการทดสอบก่อนหน้านี้แล้ว)
  3. เลือก Game Loop เป็นประเภทการทดสอบ แล้วคลิกต่อไป
  4. คลิกเรียกดู แล้วเรียกดูไฟล์ .apk ของแอป หมายเหตุ: ในขั้นตอนนี้ คุณเลือกเรียกใช้เซ็ตย่อยของการวนซ้ำแทนการเรียกใช้เพียง 1 รอบได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้การวนซ้ำหลายรายการพร้อมกันได้ที่ฟีเจอร์ที่ไม่บังคับ
  5. คลิกดำเนินการต่อ
  6. เลือกอุปกรณ์จริงที่จะใช้ทดสอบแอป
  7. คลิกเริ่มการทดสอบ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเริ่มต้นใช้งานคอนโซล Firebase ได้ที่เริ่มทดสอบด้วยคอนโซล Firebase

ใช้บรรทัดคำสั่ง gcloud (CLI)

  1. ดาวน์โหลดและติดตั้ง Google Cloud SDK หากยังไม่ได้ดำเนินการ

  2. ลงชื่อเข้าใช้ gcloud CLI โดยใช้บัญชี Google ของคุณ

    gcloud auth login

  3. ตั้งค่าโปรเจ็กต์ Firebase ใน gcloud โดยที่ PROJECT_ID คือรหัสของโปรเจ็กต์ Firebase ดังนี้

    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

ฟีเจอร์เสริม

Test Lab มีฟีเจอร์ทางเลือกมากมายที่จะช่วยให้คุณปรับแต่งการทดสอบเพิ่มเติมได้ รวมถึงความสามารถในการเขียนข้อมูลเอาต์พุต การรองรับลูปเกมหลายรายการ และป้ายกำกับสำหรับการวนซ้ำที่เกี่ยวข้อง

เขียนข้อมูลเอาต์พุต

การทดสอบ Game Loop เขียนเอาต์พุตไปยังไฟล์ที่ระบุในเมธอด launchIntent.getData() ได้ หลังจากทำการทดสอบแล้ว คุณจะเข้าถึงข้อมูลเอาต์พุตนี้ได้ในส่วน Test Lab ของคอนโซล Firebase (ดูตัวอย่างไฟล์เอาต์พุตการทดสอบ Game Loop)

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

ตัวอย่างไฟล์เอาต์พุต

คุณใช้ไฟล์ข้อมูลเอาต์พุต (ในรูปแบบเหมือนตัวอย่างด้านล่าง) เพื่อแสดงผลการทดสอบ 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 รอบสำหรับเล่นแต่ละระดับ แทนการมี 1 ลูปที่วนซ้ำไปเรื่อยๆ ด้วยวิธีนี้ หากแอปขัดข้องในระดับ 32 คุณจะเปิดใช้ลูปเกมได้โดยตรงเพื่อจำลองข้อขัดข้องและทดสอบการแก้ไขข้อบกพร่อง

วิธีทำให้แอปเรียกใช้การวนซ้ำหลายรายการพร้อมกัน

  • หากคุณกำลังทำการทดสอบด้วยตัวจัดการ Test Loop ให้ทำดังนี้

    1. เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ Manifest ของแอปภายในองค์ประกอบ <application>:

      <meta-data
        android:name="com.google.test.loops"
        android:value="5" />
      

      ความตั้งใจในการเปิดนี้มีลูปเป้าหมายเป็นพารามิเตอร์จำนวนเต็ม ในช่อง android:value คุณจะระบุจำนวนเต็มได้ตั้งแต่ 1 ถึง 1024 (จำนวนลูปสูงสุดที่อนุญาตสำหรับการทดสอบ 1 รายการ) โปรดทราบว่าระบบจะจัดทำดัชนีการวนซ้ำโดยเริ่มจาก 1 ไม่ใช่ 0

    2. ในแอป 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 ที่เกี่ยวข้องได้อย่างง่ายดาย (เช่น 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 และปัญหา OpenSSL
  • com.google.test.loops.performance: สำหรับลูปที่ใช้ทดสอบประสิทธิภาพของอุปกรณ์ ตัวอย่างเช่น เกมอาจเล่นที่การตั้งค่ากราฟิกที่ซับซ้อนที่สุดเพื่อดูว่าอุปกรณ์ใหม่ทำงานอย่างไร

วิธีทำให้แอปเรียกใช้ลูปที่มีป้ายกำกับเดียวกัน

  • หากคุณกำลังทำการทดสอบด้วยตัวจัดการ Test Loop ให้ทำดังนี้

    1. ในไฟล์ 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

    2. ในแอป 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 มีปัญหาที่ทราบดังต่อไปนี้

  • ข้อขัดข้องบางรายการไม่รองรับ Backtrace เช่น บิลด์ที่เผยแพร่บางเวอร์ชันอาจระงับเอาต์พุตของกระบวนการ debuggerd โดยใช้ prctl(PR_SET_DUMPABLE, 0) ดูข้อมูลเพิ่มเติมได้ที่ debuggerd
  • ขณะนี้ระบบยังไม่รองรับ API ระดับ 19 เนื่องจากข้อผิดพลาดเกี่ยวกับสิทธิ์ของไฟล์