Memulai pengujian Game Loop

Pengotomatisan pengujian game bisa jadi cukup sulit jika aplikasi game dibuat di framework UI yang berbeda. Dengan pengujian Game Loop, Anda dapat mengintegrasikan pengujian native dengan Test Lab dan menjalankannya dengan mudah di perangkat pilihan Anda. Pengujian Game Loop menjalankan pengujian melalui aplikasi game Anda sambil menyimulasikan tindakan pemain nyata. Panduan ini menunjukkan cara menjalankan pengujian Game Loop, lalu melihat dan mengelola hasil pengujian di Firebase console.

Bergantung pada game engine yang digunakan, Anda dapat menerapkan pengujian dengan satu atau beberapa loop. Loop adalah seluruh atau sebagian rangkaian proses pengujian di aplikasi game. Game loop dapat digunakan untuk:

  • Menjalankan level game Anda dengan cara yang sama seperti cara pengguna akhir memainkannya. Anda dapat membuat skrip input pengguna, membiarkan pengguna tidak ada aktivitas, atau mengganti pengguna dengan AI jika sesuai dengan game Anda (mis. Anda memiliki aplikasi game mobil balap dan sudah menerapkan AI. Anda dapat dengan mudah mengatur pengemudi AI untuk memberikan input pengguna).
  • Menjalankan game Anda dengan setelan kualitas tertinggi untuk melihat apakah setelan ini didukung oleh perangkat.
  • Menjalankan uji teknis (mengompilasi beberapa shader, menjalankannya, memastikan bahwa output sesuai perkiraan, dll).

Anda dapat menjalankan pengujian Game Loop pada satu perangkat uji, serangkaian perangkat uji, atau pada Test Lab. Namun, pengujian Game Loop sebaiknya tidak dijalankan di perangkat virtual karena kecepatan frame grafisnya lebih rendah daripada perangkat fisik.

Sebelum memulai

Untuk menerapkan pengujian, Anda harus terlebih dahulu mengonfigurasi aplikasi untuk pengujian Game Loop.

  1. Dalam manifes aplikasi, tambahkan filter intent baru ke aktivitas Anda:

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

    Hal ini memungkinkan Test Lab meluncurkan game Anda dengan memicunya menggunakan intent tertentu.

  2. Dalam kode Anda (sebaiknya dalam deklarasi metode onCreate), tambahkan kode berikut:

    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
    }

    Hal ini memungkinkan aktivitas Anda memeriksa intent yang meluncurkannya. Anda juga dapat menambahkan kode ini nanti jika ingin (misalnya, setelah pemuatan awal game engine).

  3. Direkomendasikan: Di akhir pengujian, tambahkan:

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    Tindakan ini akan menutup aplikasi Anda saat pengujian Game Loop selesai. Pengujian ini mengandalkan framework UI aplikasi Anda untuk memulai loop berikutnya, dan penutupan aplikasi Anda akan menandakan bahwa pengujian telah selesai.

Membuat dan menjalankan pengujian Game Loop

Setelah mengonfigurasi aplikasi untuk pengujian Game Loop, Anda dapat langsung membuat pengujian dan menjalankannya di aplikasi game. Anda dapat memilih untuk menjalankan pengujian di Test Lab menggunakan Firebase console atau antarmuka command line (CLI) gcloud, atau di perangkat lokal menggunakan Test Loop Manager.

Menjalankan pengujian di perangkat lokal

Test Loop Manager dari Test Lab adalah aplikasi open source yang membantu Anda mengintegrasikan pengujian Game Loop dan menjalankannya di perangkat lokal. Aplikasi ini juga memungkinkan tim QA Anda menjalankan game loop yang sama di perangkat mereka.

Untuk menjalankan pengujian di perangkat lokal menggunakan Test Loop Manager:

  1. Download Test Loop Manager di ponsel atau tablet, lalu instal dengan menjalankan:
    adb install testloopmanager.apk
  2. Di perangkat Anda, buka aplikasi Test Loop Apps di ponsel atau tablet. Aplikasi ini menampilkan daftar aplikasi di perangkat yang dapat dijalankan dengan game loop. Jika aplikasi game Anda tidak terlihat di sini, pastikan filter intent Anda sama dengan yang dijelaskan dalam langkah pertama di bagian Sebelum memulai.
  3. Pilih aplikasi game Anda, lalu pilih jumlah loop yang ingin dijalankan. Catatan: Pada langkah ini, Anda dapat memilih untuk menjalankan sekumpulan loop, bukan hanya satu loop. Untuk mengetahui informasi selengkapnya terkait cara menjalankan beberapa loop sekaligus, baca bagian Fitur opsional.
  4. Klik Run test. Pengujian Anda segera berjalan.

Menjalankan pengujian di Test Lab

Anda dapat menjalankan pengujian Game Loop di Test Lab menggunakan Firebase console atau gcloud CLI. Sebelum memulai, jika belum melakukannya, buka Firebase console dan buat project.

Menggunakan Firebase console

  1. Di Firebase console, klik Test Lab dari panel kiri.
  2. Klik Run Your First Test (atau Run a Test jika project Anda telah menjalankan pengujian sebelumnya).
  3. Pilih Game Loop sebagai jenis pengujian, lalu klik Continue.
  4. Klik Browse, lalu cari file .apk aplikasi Anda. Catatan: Pada langkah ini, Anda dapat memilih untuk menjalankan sekumpulan loop, bukan hanya satu loop. Untuk mengetahui informasi selengkapnya terkait cara menjalankan beberapa loop sekaligus, baca bagian Fitur opsional.
  5. Klik Continue.
  6. Pilih perangkat fisik yang akan digunakan untuk menguji aplikasi Anda.
  7. Klik Start Tests.

Untuk mengetahui informasi selengkapnya terkait cara memulai Firebase console, pelajari Memulai pengujian dengan Firebase console.

Menggunakan antarmuka command line (CLI) gcloud

  1. Jika Anda belum melakukannya, download dan instal Google Cloud SDK.

  2. Login ke gcloud CLI menggunakan Akun Google Anda:

    gcloud auth login

  3. Tetapkan project Firebase Anda di gcloud, dengan PROJECT_ID sebagai ID project Firebase Anda:

    gcloud config set project PROJECT_ID
    
  4. Jalankan pengujian pertama:

    gcloud firebase test android run \
     --type=game-loop --app=<var>path-to-apk</var> \
     --device model=herolte,version=23
    

Untuk mengetahui informasi selengkapnya terkait cara memulai gcloud CLI, pelajari Memulai pengujian dari command line gcloud.

Fitur opsional

Test Lab menawarkan beberapa fitur opsional yang memungkinkan Anda menyesuaikan pengujian lebih lanjut, termasuk kemampuan untuk menulis data output, dukungan untuk beberapa game loop, dan label untuk loop terkait.

Menulis data output

Pengujian Game Loop dapat menulis output ke file yang ditentukan dalam metode launchIntent.getData(). Setelah menjalankan pengujian, Anda dapat mengakses data output ini di bagian Test Lab pada Firebase console (lihat Contoh file output pengujian Game Loop).

Test Lab mengikuti praktik terbaik untuk berbagi file antaraplikasi yang dijelaskan dalam Berbagi File. Dalam metode onCreate() aktivitas, tempat intent Anda berada, Anda dapat memeriksa file output data dengan menjalankan kode berikut:

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());
    // ...
}

Jika ingin menulis ke file dari sisi C++ aplikasi game, Anda dapat meneruskan dalam deskriptor file, bukan jalur file:

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

Contoh file output

Anda dapat menggunakan file data output (diformat seperti contoh di bawah) untuk menampilkan hasil pengujian game loop di bagian Test Lab pada 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
}

Lebih dari satu game loop

Mungkin Anda perlu menjalankan lebih dari satu game loop di aplikasi. Satu loop adalah seluruh proses lengkap yang menjalankan aplikasi game dari awal hingga akhir. Misalnya, jika Anda memiliki beberapa level dalam game, Anda sebaiknya menggunakan satu game loop untuk memainkan masing-masing level, bukan hanya satu loop yang meliputi semua level. Dengan demikian, jika aplikasi mengalami error di level 32, Anda dapat langsung meluncurkan game loop tersebut untuk mereproduksi error dan menguji perbaikan bug.

Agar aplikasi Anda dapat menjalankan beberapa loop sekaligus:

  • Jika menjalankan pengujian dengan Test Loop Manager:

    1. Tambahkan baris berikut ke manifes aplikasi Anda, di dalam elemen <application>:

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

      Intent peluncuran ini berisi loop target sebagai parameter bilangan bulat. Di kolom android:value, Anda dapat menentukan bilangan bulat dari 1 hingga 1024 (jumlah maksimum loop yang diizinkan untuk satu pengujian). Perhatikan bahwa loop diindeks mulai dari 1, bukan 0.

    2. Di aplikasi Test Loop Manager, akan muncul layar pilihan yang memungkinkan Anda memilih loop mana yang ingin dijalankan. Jika Anda memilih beberapa loop, setiap loop akan diluncurkan secara berurutan setelah loop sebelumnya selesai.

  • Jika menjalankan pengujian dengan Firebase console, masukkan daftar atau rentang nomor loop di kolom Scenarios.

  • Jika menjalankan pengujian dengan gcloud CLI, tentukan daftar nomor loop menggunakan flag --scenario-numbers. Misalnya, --scenario-numbers=1,3,5 menjalankan loop 1, 3, dan 5.

  • Jika menulis C++ dan ingin mengubah perilaku loop, teruskan tambahan berikut ke kode C++ native:

    Kotlin+KTX

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

    Java

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

    Sekarang Anda dapat mengubah perilaku loop berdasarkan nilai int yang dihasilkan.

Memberi label game loop

Jika game loop diberi satu atau beberapa label skenario, Anda dan tim QA dapat dengan mudah meluncurkan serangkaian game loop terkait (mis. "semua game loop kompatibilitas") dan mengujinya dalam satu matriks. Anda dapat membuat label sendiri atau menggunakan label bawaan yang ditawarkan oleh Test Lab:

  • 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 mengeksekusi kode GPU yang mungkin tidak berjalan dengan baik dalam production, guna mengungkap masalah pada 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.

Agar aplikasi Anda dapat menjalankan loop dengan label yang sama:

  • Jika menjalankan pengujian dengan Test Loop Manager:

    1. Dalam manifes aplikasi Anda, tambahkan baris meta-data berikut dan ganti LABEL_NAME dengan label pilihan Anda:

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

      Di kolom android:value, Anda dapat menentukan rentang atau serangkaian bilangan bulat dari 1 hingga 1024 (jumlah maksimum loop yang diizinkan untuk satu pengujian) yang mewakili loop yang ingin Anda beri label. Perhatikan bahwa loop diindeks mulai dari 1, bukan 0. Misalnya, android:value="1,3-5" menerapkan LABEL_NAME ke loop 1, 3, 4, dan 5.

    2. Di aplikasi Test Loop Manager, masukkan satu atau beberapa label di kolom Labels.

  • Jika menjalankan pengujian dengan Firebase console, masukkan satu atau beberapa label di kolom Labels.

  • Jika menjalankan pengujian dengan gcloud CLI, tentukan satu atau beberapa label skenario menggunakan flag --scenario-labels (mis. --scenario-labels=performance,gpu).

Dukungan pemberian lisensi aplikasi

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

Masalah umum

Pengujian Game Loop di Test Lab memiliki masalah umum berikut:

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