Pengujian Game Loop dari Firebase Test Lab

Mengotomatisasi pengujian game sangat menantang karena begitu banyaknya framework UI yang digunakan untuk pengembangan game (beberapa di antaranya bergantung pada engine), dan kesulitan dalam mengotomatisasi navigasi UI dalam game. Untuk mendukung pengujian aplikasi game, Test Lab kini menyertakan dukungan untuk menggunakan "mode demo", yang membuat aplikasi game berjalan sambil menyimulasikan tindakan pemain. Mode ini dapat menyertakan beberapa loop (atau skenario), yang dapat diatur secara logis menggunakan label sehingga Anda dapat menjalankan beberapa loop yang berhubungan secara bersamaan.

Dokumen ini memberikan panduan tentang cara mengimplementasikan game loop untuk memudahkan Anda dalam menggunakannya saat menguji game selama pengembangan. Panduan ini berlaku ketika Anda menjalankan pengujian pada satu perangkat uji, pada beberapa perangkat uji, atau menggunakan Test Lab.

Mulai

Untuk menggunakan uji game loop di Test Lab, game Anda harus dimodifikasi untuk dapat melakukan hal berikut:

  1. Meluncurkan loop
  2. Menjalankan loop
  3. (Opsional) Menutup aplikasi game

Meluncurkan loop

Saat meluncurkan uji game loop, game Anda dipicu dengan intent tertentu, sehingga Anda harus mengubah manifes dan menambahkan filter intent baru pada aktivitas Anda, seperti yang ditunjukkan pada kode contoh berikut:

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

Menjalankan loop

Ketika diluncurkan, aktivitas Anda memeriksa intent mana yang meluncurkannya, seperti yang ditunjukkan pada contoh kode berikut:

Java
Android

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
}

Kotlin
Android

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
}

Sebaiknya jalankan kode ini dalam metode onCreate Anda, tetapi Anda dapat menjalankannya nanti jika mau (misalnya, setelah memuat game engine Anda terlebih dulu). Lalu Anda dapat mengimplementasikan game loop (atau lebih dari satu loop seperti yang dijelaskan di Lebih dari satu game loop) sesuai keinginan, tergantung game engine Anda. Sebagai contoh, game loop bisa digunakan untuk:

  • Menjalankan level game Anda dengan cara yang sama seperti cara pengguna akhir akan memainkannya. Anda bisa menulis skrip input dari pengguna, membiarkan pengguna menganggur, atau mengganti pengguna dengan AI jika sesuai untuk game Anda (misalnya, jika Anda sudah mengimplementasikan AI, seperti dalam game balap mobil, dan Anda dapat dengan mudah memasukkan pengemudi AI yang bertanggung jawab atas input pengguna).
  • Menjalankan game Anda dengan setelan kualitas tertinggi untuk melihat apakah perangkat mendukungnya atau tidak.
  • Menjalankan uji teknis (mengumpulkan beberapa shader, menjalankannya, memastikan bahwa output sesuai perkiraan, dll).

Test Loop Manager

Untuk membantu Anda mengintegrasikan game loop dan menjalankannya di perangkat lokal, serta membantu tim QA Anda menjalankan game loop di perangkat mereka, kami menyediakan aplikasi open source yang disebut Test Loop Manager.

Untuk menggunakan Test Loop Manager, lakukan hal berikut:

  1. Download Test Loop Manager.
  2. Instal Test Loop Manager pada perangkat Anda, menggunakan perintah berikut:
    adb install testloopmanager.apk
  3. Buka aplikasi (bernama "Test Loop Apps") di ponsel atau tablet Anda; dan Anda akan melihat daftar aplikasi di perangkat yang berisi game loop. Jika aplikasi Anda tidak terlihat di sini, pastikan filter intent Anda cocok dengan yang dijelaskan dalam Meluncurkan loop.
  4. Pilih aplikasi game yang ingin Anda uji.
    1. Setelah mengklik nama aplikasi game dari daftar, pilih skenario (yaitu, game loop) yang diimplementasikan aplikasi Anda. Jika aplikasi Anda mengimplementasikan beberapa loop, lihat Lebih dari satu game loop.
    2. Klik Jalankan pengujian, dan perhatikan ketika skenario dijalankan.

Menutup aplikasi game

Di akhir pengujian, Anda harus menutup aplikasi dengan menggunakan:

Java
Android

yourActivity.finish();

Kotlin
Android

yourActivity.finish()

Umumnya, uji game loop memungkinkan framework UI untuk memulai loop berikutnya. Jika Anda tidak menutup aplikasi, framework UI yang menjalankan loop Anda tidak akan tahu bahwa pengujian telah selesai, dan mungkin akan menghentikan aplikasi setelah beberapa waktu berlalu.

Menjalankan uji game loop di Test Lab

Buka Firebase console dan buat project jika Anda belum memilikinya. Untuk menggunakan Test Lab secara gratis, tetapi dengan kuota harian terbatas, gunakan paket penagihan Spark. Untuk mempelajari tentang cara menggunakan Test Lab tanpa batas penggunaan, lihat Paket Harga Firebase.

Menggunakan Firebase console

Gunakan petunjuk berikut untuk menjalankan uji game loop menggunakan Firebase console:

  1. Di Firebase console, klik Test Lab di panel navigasi kiri.
  2. Klik Jalankan Pengujian Pertama Anda (atau Jalankan Pengujian, jika project Anda telah menjalankan pengujian sebelumnya).
  3. Pilih Game Loop sebagai jenis pengujian, lalu klik Lanjutkan.
  4. Klik Cari, lalu temukan file .apk aplikasi Anda.
  5. (Opsional) Untuk memilih subset skenario yang tersedia (game loop), lakukan salah satu hal berikut:

    • Untuk memilih skenario tertentu, masukkan daftar atau rentang nomor skenario di kolom Skenario.
    • Untuk memilih semua skenario yang memiliki label tertentu, masukkan satu atau beberapa label skenario di kolom Label.
  6. Klik Lanjutkan.

  7. Pilih perangkat fisik yang akan digunakan untuk menguji aplikasi Anda.

  8. Klik Mulai Pengujian.

Untuk informasi lebih lanjut tentang Firebase Console, lihat Menggunakan Firebase Test Lab dari Firebase console.

Menggunakan lingkungan baris perintah gcloud

Gunakan petunjuk berikut untuk menjalankan uji game loop menggunakan lingkungan baris perintah gcloud (CLI):

  1. Jika Anda belum memiliki project Firebase, buka Firebase console, lalu klik Tambahkan project untuk membuat project.
  2. Instal Google Cloud SDK yang menyertakan gcloud CLI.
  3. Login menggunakan akun Google:

    gcloud auth login

  4. Tetapkan project Firebase Anda menggunakan perintah berikut, dengan PROJECT_ID sebagai project Firebase yang Anda buat di langkah 1:

    gcloud config set project PROJECT_ID
    
  5. Jalankan pengujian pertama Anda, sebagai berikut:

    gcloud firebase test android run \
    --type=game-loop --app=<path-to-apk> \
    --device model=herolte,version=23
  6. (Opsional) Untuk memilih subset skenario yang tersedia (game loop), lakukan salah satu hal berikut saat Anda menjalankan uji game loop:

    • Untuk memilih skenario tertentu, tentukan daftar nomor skenario menggunakan tanda --scenario-numbers (misalnya, --scenario-numbers=1,3,5).
    • Untuk memilih semua skenario dengan label khusus, tentukan satu atau beberapa label skenario menggunakan tanda --scenario-labels (misalnya, --scenario-labels=performance,gpu).

Untuk informasi lebih lanjut tentang penggunaan CLI gcloud dengan Test Lab, lihat Menggunakan Firebase Test Lab for Android dari Command Line gcloud.

Fitur opsional

Bagian ini menjelaskan cara menggunakan fitur opsional, seperti menulis data ke file output, mendukung beberapa game loop, dan memberi label pada loop yang berhubungan sehingga Anda dapat menguji loop yang berhubungan dengan mudah dalam satu matriks uji.

Menulis data output

Game loop Anda dapat menulis output ke file yang disediakan menggunakan metode launchIntent.getData(). Data output ini dapat ditampilkan oleh Test Lab pada halaman hasil pengujian. Untuk melihat contoh file data output, buka Contoh file output uji game loop.

Test Lab mengikuti praktik terbaik untuk berbagi file antara aplikasi yang dijelaskan di Berbagi File. Dalam metode onCreate() Aktivitas, tempat Anda mengambil intent, Anda juga dapat memeriksa file tersebut dengan menggunakan kode berikut:

Java
Android

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    // ...
}

Kotlin
Android

val launchIntent = intent
val logFile = launchIntent.data
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.encodedPath!!)
    // ...
}

Jika Anda ingin menulis ke file itu dari sisi C++ aplikasi game, Anda akan meneruskan deskriptor file, bukan lokasi file, seperti yang ditunjukkan pada kode contoh berikut:

Java
Android

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

Kotlin
Android

val launchIntent = intent
val logFile = launchIntent.data
var fd = -1
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.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);

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

Lebih dari satu game loop

Anda juga dapat mendukung beberapa game loop di aplikasi game Anda. Misalnya, jika Anda memiliki beberapa level dalam game, Anda sebaiknya menggunakan satu game loop yang akan diluncurkan di setiap level, bukan hanya satu loop yang diulang di semua level.

Dengan begitu, jika aplikasi Anda mengalami error di level 32, Anda dapat langsung meluncurkan game loop tersebut untuk mencoba dan mereproduksi error, serta menguji perbaikan bug.

Misalnya, jika Anda memiliki 5 game loop di aplikasi, Anda hanya perlu menambahkan 1 baris ke file manifes aplikasi Anda, di dalam elemen <application>:

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

Lalu, ketika meluncurkan Test Loop Manager, Anda dapat menggunakan layar pemilihan untuk memilih game loop yang akan diluncurkan. Jika Anda memilih untuk meluncurkan lebih dari satu loop, Test Loop Manager meluncurkan setiap loop secara berurutan setelah loop sebelumnya selesai. Dengan Test Lab, Anda memilih loop yang akan diluncurkan.

Intent peluncuran berisi loop target sebagai parameter bilangan bulat, dalam rentang 1 hingga jumlah maksimum loop yang didukung.

Anda bisa membaca ekstra dari intent di Java seperti yang ditunjukkan pada contoh kode berikut ini:

Java
Android

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

Kotlin
Android

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

Lalu, Anda dapat meneruskan ekstra ini ke kode C++ bawaan untuk mengubah perilaku loop berdasarkan nilai int yang dihasilkan.

Memberi label game loop

Anda dapat memberi label game loop Anda dengan satu atau beberapa label skenario untuk mempermudah tim QA meluncurkan serangkaian game loop yang berhubungan (misalnya, "semua game loop kompatibilitas"). Untuk melakukan ini, Anda harus menambahkan baris meta-data ke file manifes aplikasi yang serupa dengan contoh berikut:

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

Anda dapat membuat label Anda sendiri, dan kami juga menyediakan 4 label bawaan:

  • com.google.test.loops.player_experience: Untuk loop yang mereproduksi pengalaman pengguna yang sebenarnya saat memainkan game. Pengujian dengan loop ini bertujuan untuk menemukan masalah yang akan dihadapi pengguna sesungguhnya saat memainkan game ini nantinya.
  • com.google.test.loops.gpu_compatibility: Untuk loop yang menguji masalah terkait GPU. Pengujian dengan loop ini bertujuan untuk menjalankan kode GPU yang mungkin tidak berjalan dengan baik dalam produksi, untuk mengungkap masalah dengan hardware dan driver.
  • com.google.test.loops.compatibility: Untuk loop yang menguji berbagai masalah kompatibilitas, termasuk masalah I/O dan OpenSSL.
  • com.google.test.loops.performance: Untuk loop yang menguji performa perangkat. Misalnya, game dapat dijalankan dengan setelan grafis yang paling rumit untuk melihat perilaku perangkat baru.

Dukungan pemberian lisensi aplikasi

Test Lab mendukung aplikasi yang menggunakan layanan Pemberian Lisensi Aplikasi yang ditawarkan oleh Google Play. Untuk dapat memeriksa pemberian lisensi saat menguji aplikasi Anda dengan Test Lab, Anda harus memublikasikan aplikasi Anda ke channel produksi di Play Store. Untuk menguji aplikasi Anda di channel alfa atau beta menggunakan Test Lab, hapus pemeriksaan pemberian lisensi sebelum mengupload aplikasi ke Test Lab.

Masalah umum

Uji Game loop di Test Lab memiliki masalah umum berikut:

  • Dukungan terbatas untuk Khronos Vulkan API. Hanya perangkat berikut yang tersedia di Test Lab yang mendukung Vulkan API: Samsung Galaxy S7 (API level 24), Google Pixel (API level 25).
  • Beberapa error tidak mendukung backtrace. Misalnya, beberapa build rilis mungkin menyembunyikan output proses debuggerd menggunakan prctl(PR_SET_DUMPABLE, 0). Untuk mempelajari lebih lanjut, lihat debuggerd.
  • API Level 19 saat ini tidak didukung karena adanya error pada izin file.

Contoh file output uji game loop

Anda bisa menggunakan file data output yang diformat seperti yang ditunjukkan pada contoh di bawah ini untuk menampilkan hasil uji game loop di Firebase console. Area yang ditampilkan sebagai /.../ dapat berisi kolom kustom apa saja yang Anda butuhkan selama tidak bertentangan dengan nama kolom lain yang digunakan dalam file ini:

{
  "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
}

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.