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

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

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

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

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

ก่อนที่คุณจะเริ่มต้น

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

  1. ในไฟล์ Manifest ของแอป ให้เพิ่มตัวกรองความตั้งใจใหม่ให้กับ กิจกรรม ของคุณ :

    <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 Manager

เรียกใช้บนอุปกรณ์ท้องถิ่น

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

ในการเรียกใช้การทดสอบบนอุปกรณ์ภายในเครื่องโดยใช้ Test Loop Manager:

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

เรียกใช้ในห้องปฏิบัติการทดสอบ

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

ใช้คอนโซล Firebase

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

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

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

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

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

    gcloud auth login

  3. ตั้งค่าโครงการ Firebase ของคุณใน gcloud โดยที่ PROJECT_ID คือ 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() ของกิจกรรมของคุณ ซึ่งเป็นที่ตั้งของความตั้งใจของคุณ คุณสามารถตรวจสอบไฟล์เอาต์พุตข้อมูลของคุณโดยรันโค้ดต่อไปนี้:

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

ภาษาซี++

#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 หนึ่งรอบเพื่อเริ่มแต่ละด่านแทนที่จะมี 1 ลูปวนซ้ำไปซ้ำมาทั้งหมด ด้วยวิธีนี้ หากแอปของคุณขัดข้องที่ระดับ 32 คุณสามารถเปิด Game Loop นั้นโดยตรงเพื่อจำลองการหยุดทำงานและทดสอบการแก้ไขข้อบกพร่อง

วิธีเปิดใช้งานแอปของคุณเพื่อเรียกใช้หลายลูปพร้อมกัน:

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

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

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

      จุดประสงค์ในการเรียกใช้นี้มีลูปเป้าหมายเป็นพารามิเตอร์จำนวนเต็ม ในช่อง 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+KTX

    val launchIntent = intent
    val scenario = launchIntent.getIntExtra("scenario", 0)

    Java

    Intent launchIntent = getIntent();
    int scenario = launchIntent.getIntExtra("scenario", 0);

    ตอนนี้คุณสามารถเปลี่ยนลักษณะการทำงานของลูปตามค่า int ที่ได้

ลูปเกมฉลาก

เมื่อคุณติดป้ายกำกับ Game Loop ของคุณด้วยป้ายกำกับสถานการณ์อย่างน้อยหนึ่งป้าย คุณและทีม QA ของคุณสามารถเปิดชุด Game Loop ที่เกี่ยวข้องกันได้อย่างง่ายดาย (เช่น "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 และปัญหา 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 ให้ป้อนป้ายกำกับอย่างน้อยหนึ่งรายการในช่อง ป้ายกำกับ

  • หากคุณกำลังเรียกใช้การทดสอบกับคอนโซล Firebase ให้ป้อนป้ายกำกับอย่างน้อยหนึ่งรายการในช่อง ป้ายกำกับ

  • หากคุณกำลังเรียกใช้การทดสอบด้วย gcloud CLI ให้ระบุป้ายกำกับสถานการณ์อย่างน้อยหนึ่งป้ายโดยใช้แฟล็ก --scenario-labels (เช่น --scenario-labels=performance,gpu )

การสนับสนุนสิทธิ์ใช้งานแอป

Test Lab รองรับแอพที่ใช้บริการ App Licensing จาก Google Play หากต้องการตรวจสอบใบอนุญาตให้สำเร็จเมื่อทดสอบแอปกับ Test Lab คุณต้องเผยแพร่แอปไปยังช่องทางการผลิตใน Play Store หากต้องการทดสอบแอปของคุณในช่องอัลฟ่าหรือเบต้าโดยใช้ Test Lab ให้นำการตรวจสอบสิทธิ์การใช้งานออกก่อนอัปโหลดแอปไปยัง Test Lab

ปัญหาที่ทราบ

การทดสอบ Game Loop ใน Test Lab มีปัญหาที่ทราบดังต่อไปนี้:

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