เริ่มต้นใช้งานการทดสอบ 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. ในรายการแอปของคุณ ให้เพิ่มตัวกรองความตั้งใจใหม่ให้กับ กิจกรรม ของคุณ :

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

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

การทดสอบ 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++ ของแอพเกมของคุณ คุณสามารถส่งผ่าน file descriptor แทนเส้นทางของไฟล์ได้:

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

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

คุณสามารถใช้ไฟล์ข้อมูลเอาต์พุต (ตามรูปแบบตัวอย่างด้านล่าง) เพื่อแสดงผลการทดสอบลูปเกมในส่วน 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
}

เกมวนซ้ำหลายรอบ

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

หากต้องการให้แอปของคุณทำงานหลายลูปพร้อมกัน:

  • หากคุณกำลังทำการทดสอบกับ 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 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. ในรายการของแอปของคุณ ให้เพิ่มบรรทัดข้อมูลเมตาต่อไปนี้และแทนที่ 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 ให้ป้อนป้ายกำกับอย่างน้อย 1 รายการในช่อง ป้ายกำกับ

  • หากคุณกำลังเรียกใช้การทดสอบด้วย gcloud CLI ให้ระบุป้ายกำกับสถานการณ์อย่างน้อย 1 รายการโดยใช้แฟล็ก --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 เนื่องจากข้อผิดพลาดในการอนุญาตไฟล์