เริ่มต้นใช้งานการทดสอบ 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 เปิดเกมของคุณได้โดยการทริกเกอร์ด้วย Intent ที่เฉพาะเจาะจง

  2. เพิ่มโค้ดต่อไปนี้ในโค้ดของคุณ (เราแนะนำให้เพิ่มภายในประกาศเมธอด 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 ที่เปิดกิจกรรมได้ นอกจากนี้ คุณยังเพิ่มโค้ดนี้ในภายหลังได้หากต้องการ (เช่น หลังจากโหลดเอนจินเกมในตอนแรก)

  3. แนะนำ: เพิ่มโค้ดต่อไปนี้เมื่อสิ้นสุดการทดสอบ

    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

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

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

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

ใช้คอนโซล Firebase

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

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

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

  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 หลายรายการ และป้ายกำกับสำหรับลูปที่เกี่ยวข้อง

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

การทดสอบ 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 ให้ทำดังนี้

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

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

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

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

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

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

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

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