Làm quen với bài kiểm thử Vòng lặp trò chơi

Có thể khó tự động hoá việc kiểm thử trò chơi khi các ứng dụng trò chơi được xây dựng trên nhiều khung giao diện người dùng. Kiểm thử Vòng lặp trò chơi cho phép bạn tích hợp các kiểm thử gốc với Phòng thử nghiệm và dễ dàng chạy các kiểm thử đó trên các thiết bị bạn chọn. Kiểm thử Vòng lặp trò chơi chạy kiểm thử thông qua ứng dụng trò chơi của bạn trong khi mô phỏng các hành động của người chơi thực. Hướng dẫn này trình bày cách chạy quy trình kiểm thử Vòng lặp trò chơi, sau đó xem và quản lý kết quả kiểm thử trong bảng điều khiển của Firebase.

Tuỳ thuộc vào công cụ phát triển trò chơi, bạn có thể triển khai các bài kiểm thử bằng một hoặc nhiều vòng lặp. Vòng lặp là hoạt động chạy toàn bộ hoặc một phần của kiểm thử trên ứng dụng trò chơi. Bạn có thể sử dụng vòng lặp trò chơi để:

  • Chạy một cấp độ của trò chơi giống như cách người dùng cuối chơi. Bạn có thể viết tập lệnh cho đầu vào của người dùng, cho phép người dùng ở trạng thái rảnh hoặc thay thế người dùng bằng một AI nếu AI đó phù hợp với trò chơi (ví dụ: giả sử bạn có ứng dụng trò chơi trên xe đua và đã triển khai AI). Bạn có thể dễ dàng giao cho người lái xe AI phụ trách hoạt động đầu vào của người dùng).
  • Chạy trò chơi của bạn ở chế độ cài đặt chất lượng cao nhất để xem thiết bị có hỗ trợ trò chơi này hay không.
  • Chạy chương trình kiểm thử kỹ thuật (biên dịch nhiều chương trình đổ bóng, thực thi, kiểm tra để đảm bảo kết quả như dự kiến, v.v.).

Bạn có thể chạy kiểm thử Vòng lặp trò chơi trên một thiết bị kiểm thử, một nhóm thiết bị kiểm thử hoặc trên Phòng thử nghiệm. Tuy nhiên, bạn không nên chạy kiểm thử Game Loop trên thiết bị ảo vì chúng có tốc độ khung hình đồ hoạ thấp hơn thiết bị thực.

Trước khi bắt đầu

Để triển khai kiểm thử, trước tiên, bạn phải định cấu hình ứng dụng cho việc kiểm thử Vòng lặp trò chơi.

  1. Trong tệp kê khai ứng dụng, hãy thêm một bộ lọc ý định mới vào hoạt động:

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

    Điều này cho phép Phòng thử nghiệm khởi chạy trò chơi của bạn bằng cách kích hoạt trò chơi đó với một ý định cụ thể.

  2. Trong mã của bạn (nên có bên trong nội dung khai báo phương thức onCreate), hãy thêm nội dung sau:

    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
    }

    Thao tác này cho phép hoạt động của bạn kiểm tra ý định khởi chạy ý định đó. Bạn cũng có thể thêm mã này sau nếu muốn (ví dụ: sau khi tải công cụ phát triển trò chơi lần đầu).

  3. Đề xuất: Ở cuối thử nghiệm, hãy thêm:

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    Thao tác này sẽ đóng ứng dụng khi quá trình kiểm thử Vòng lặp trò chơi hoàn tất. Quá trình kiểm thử dựa vào khung giao diện người dùng của ứng dụng để bắt đầu vòng lặp tiếp theo. Việc đóng ứng dụng sẽ cho biết rằng kiểm thử đã hoàn tất.

Tạo và chạy kiểm thử Vòng lặp trò chơi

Sau khi định cấu hình ứng dụng cho kiểm thử Vòng lặp trò chơi, bạn có thể tạo ngay một bài kiểm thử và chạy trong ứng dụng trò chơi của mình. Bạn có thể chọn chạy kiểm thử trong Phòng thử nghiệm bằng cách sử dụng bảng điều khiển của Firebase hoặc giao diện dòng lệnh gcloud (CLI) hoặc trên thiết bị cục bộ bằng Trình quản lý vòng lặp kiểm thử.

Chạy trên thiết bị cục bộ

Test Loop Manager (Trình quản lý vòng lặp kiểm thử) của Phòng thử nghiệm là một ứng dụng nguồn mở giúp bạn tích hợp các bài kiểm thử trong Game Loop (Vòng lặp trò chơi) và chạy các bài kiểm thử đó trên các thiết bị cục bộ. Qua đó, nhóm Đảm bảo chất lượng của bạn có thể chạy cùng một vòng lặp trò chơi trên các thiết bị của họ.

Cách chạy kiểm thử trên thiết bị cục bộ bằng Trình quản lý vòng lặp kiểm thử:

  1. Tải Test Loop Manager (Trình quản lý vòng lặp kiểm thử) xuống điện thoại hoặc máy tính bảng rồi cài đặt bằng cách chạy:
    adb install testloopmanager.apk
  2. Trên thiết bị, hãy mở ứng dụng Test Loop Apps (Kiểm thử ứng dụng vòng lặp) trên điện thoại hoặc máy tính bảng. Ứng dụng sẽ hiển thị danh sách các ứng dụng trên thiết bị có thể chạy bằng vòng lặp trò chơi. Nếu bạn không thấy ứng dụng trò chơi của mình ở đây, hãy đảm bảo bộ lọc ý định khớp với bộ lọc được mô tả trong bước đầu tiên của phần Trước khi bắt đầu.
  3. Chọn ứng dụng trò chơi của bạn, sau đó chọn số vòng lặp mà bạn muốn chạy. Lưu ý: Ở bước này, bạn có thể chọn chạy một tập hợp con các vòng lặp thay vì chỉ một vòng lặp. Để biết thêm thông tin về cách chạy nhiều vòng lặp cùng một lúc, hãy xem phần Các tính năng không bắt buộc.
  4. Nhấp vào Run test (Chạy kiểm thử). Thử nghiệm của bạn sẽ bắt đầu chạy ngay lập tức.

Chạy trong Phòng thử nghiệm

Bạn có thể chạy kiểm thử Vòng lặp trò chơi trong Phòng thử nghiệm bằng cách sử dụng bảng điều khiển của Firebase hoặc gcloud CLI. Trước khi bắt đầu, hãy mở bảng điều khiển của Firebase rồi tạo một dự án (nếu bạn chưa thực hiện).

Sử dụng bảng điều khiển của Firebase

  1. Trong bảng điều khiển của Firebase, hãy nhấp vào Phòng thử nghiệm trên bảng điều khiển bên trái.
  2. Nhấp vào Run Your First Test (Chạy kiểm thử đầu tiên của bạn) (hoặc Run a Test (Chạy kiểm thử) nếu dự án của bạn đã chạy một kiểm thử trước đó).
  3. Chọn loại kiểm thử là Game Loop (Vòng lặp trò chơi), sau đó nhấp vào Continue (Tiếp tục).
  4. Nhấp vào Browse (Duyệt qua) rồi duyệt đến tệp .apk của ứng dụng. Lưu ý: Ở bước này, bạn có thể chọn chạy một tập hợp con các vòng lặp thay vì chỉ một vòng lặp. Để biết thêm thông tin về cách chạy nhiều vòng lặp cùng một lúc, hãy xem phần Các tính năng không bắt buộc.
  5. Nhấp vào Tiếp tục.
  6. Chọn thiết bị thực mà bạn muốn dùng để kiểm thử ứng dụng.
  7. Nhấp vào Start Test (Bắt đầu kiểm thử).

Để biết thêm thông tin về cách bắt đầu sử dụng bảng điều khiển của Firebase, hãy xem bài viết Bắt đầu kiểm thử bằng bảng điều khiển của Firebase.

Sử dụng dòng lệnh gcloud (CLI)

  1. Tải Google Cloud SDK xuống và cài đặt nếu bạn chưa có

  2. Đăng nhập vào gcloud CLI bằng Tài khoản Google của bạn:

    gcloud auth login

  3. Đặt dự án Firebase của bạn trong gcloud, trong đó PROJECT_ID là mã nhận dạng của dự án Firebase:

    gcloud config set project PROJECT_ID
    
  4. Chạy kiểm thử đầu tiên của bạn:

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

Để biết thêm thông tin về cách bắt đầu sử dụng gcloud CLI, hãy xem phần Bắt đầu kiểm thử từ dòng lệnh gcloud.

Các tính năng không bắt buộc

Phòng thử nghiệm cung cấp một số tính năng không bắt buộc cho phép bạn tuỳ chỉnh thêm các kiểm thử của mình, bao gồm cả khả năng ghi dữ liệu đầu ra, hỗ trợ nhiều vòng lặp trò chơi và nhãn cho các vòng lặp liên quan.

Ghi dữ liệu đầu ra

Bài kiểm thử Vòng lặp trò chơi có thể ghi kết quả vào tệp được chỉ định trong phương thức launchIntent.getData(). Sau khi chạy kiểm thử, bạn có thể truy cập dữ liệu đầu ra này trong phần Phòng thử nghiệm của bảng điều khiển của Firebase (xem ví dụ về tệp đầu ra kiểm thử Vòng lặp trò chơi).

Phòng thử nghiệm tuân theo các phương pháp hay nhất để chia sẻ tệp giữa các ứng dụng được mô tả trong phần Chia sẻ tệp. Trong phương thức onCreate() của hoạt động, nơi đặt ý định của bạn, bạn có thể kiểm tra tệp đầu ra dữ liệu bằng cách chạy mã sau:

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

Nếu muốn ghi vào tệp từ phía C++ của ứng dụng trò chơi, bạn có thể chuyển chỉ số mô tả tệp thay vì đường dẫn tệp:

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

Ví dụ về tệp đầu ra

Bạn có thể sử dụng các tệp dữ liệu đầu ra (có định dạng như ví dụ bên dưới) để hiển thị kết quả kiểm thử vòng lặp trò chơi trong phần Phòng thử nghiệm trên bảng điều khiển của Firebase. Các vùng được hiển thị dưới dạng /.../ có thể chứa bất kỳ trường tuỳ chỉnh nào bạn cần, miễn là các vùng đó không xung đột với tên của các trường khác dùng trong tệp này:

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

Nhiều vòng lặp trò chơi

Bạn có thể thấy hữu ích khi chạy nhiều vòng lặp trò chơi trong ứng dụng của mình. Vòng lặp là một hoạt động chạy trọn vẹn ứng dụng trò chơi từ đầu đến cuối. Ví dụ: nếu có nhiều cấp độ trong trò chơi, bạn nên có một vòng lặp trò chơi để khởi chạy từng cấp thay vì có một vòng lặp lặp lại qua tất cả các cấp đó. Nhờ đó, nếu ứng dụng của bạn gặp sự cố ở cấp 32, thì bạn có thể trực tiếp khởi chạy vòng lặp trò chơi đó để tái tạo sự cố và kiểm thử các bản sửa lỗi.

Cách cho phép ứng dụng chạy nhiều vòng lặp cùng một lúc:

  • Nếu bạn đang chạy kiểm thử bằng Trình quản lý vòng lặp kiểm thử:

    1. Hãy thêm dòng sau vào tệp kê khai của ứng dụng, bên trong phần tử <application>:

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

      Ý định chạy này chứa vòng lặp đích dưới dạng một tham số số nguyên. Trong trường android:value, bạn có thể chỉ định một số nguyên từ 1 đến 1024 (số vòng lặp tối đa được phép cho một kiểm thử). Xin lưu ý rằng các vòng lặp được lập chỉ mục bắt đầu từ 1, chứ không phải từ 0.

    2. Trong ứng dụng Test Loop Manager (Trình quản lý vòng lặp kiểm thử), màn hình lựa chọn sẽ xuất hiện cho phép bạn chọn (các) vòng lặp bạn muốn chạy. Nếu bạn chọn nhiều vòng lặp, thì mỗi vòng lặp sẽ được khởi chạy theo trình tự sau khi vòng lặp trước đó hoàn tất.

  • Nếu bạn đang chạy kiểm thử bằng bảng điều khiển của Firebase, hãy nhập một danh sách hoặc một phạm vi số vòng lặp trong trường Scenarios (Tình huống).

  • Nếu bạn đang chạy kiểm thử với CLI gcloud, hãy chỉ định danh sách số vòng lặp bằng cách sử dụng cờ --scenario-numbers. Ví dụ: --scenario-numbers=1,3,5 chạy các vòng lặp 1, 3 và 5.

  • Nếu bạn đang viết C++ và muốn thay đổi hành vi của vòng lặp, hãy truyền thêm nội dung sau vào mã C++ gốc:

    Kotlin+KTX

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

    Java

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

    Giờ đây, bạn có thể thay đổi hành vi của vòng lặp dựa trên giá trị int nhận được.

Nhãn vòng lặp trò chơi

Khi gắn nhãn vòng lặp trò chơi bằng một hoặc nhiều nhãn tình huống, bạn và nhóm đảm bảo chất lượng có thể dễ dàng khởi chạy một tập hợp các vòng lặp trò chơi có liên quan (ví dụ: "tất cả vòng lặp trò chơi tương thích") và thử nghiệm chúng trong một ma trận duy nhất. Bạn có thể tạo nhãn của riêng mình hoặc sử dụng các nhãn được xác định trước do Phòng thử nghiệm cung cấp:

  • com.google.test.loops.player_experience: Đối với vòng lặp dùng để tái hiện trải nghiệm thực của người dùng khi chơi trò chơi. Mục tiêu của việc kiểm thử các vòng lặp này là tìm ra những vấn đề mà người dùng thực sẽ gặp phải khi chơi trò chơi.
  • com.google.test.loops.gpu_compatibility: Vòng lặp for dùng để kiểm thử các vấn đề liên quan đến GPU. Mục tiêu của việc kiểm thử các vòng lặp này là thực thi mã GPU có thể không chạy đúng cách khi chạy chính thức, để gặp vấn đề về phần cứng và trình điều khiển.
  • com.google.test.loops.compatibility: Đối với vòng lặp dùng để kiểm thử nhiều vấn đề về khả năng tương thích, bao gồm cả vấn đề I/O và vấn đề OpenSSL.
  • com.google.test.loops.performance: Vòng lặp for dùng để kiểm thử hiệu suất của thiết bị. Ví dụ: một trò chơi có thể chạy ở các chế độ cài đặt đồ hoạ phức tạp nhất để xem hành vi của thiết bị mới.

Cách cho phép ứng dụng chạy các vòng lặp có cùng nhãn:

  • Nếu bạn đang chạy kiểm thử bằng Trình quản lý vòng lặp kiểm thử:

    1. Trong tệp kê khai của ứng dụng, hãy thêm dòng siêu dữ liệu sau đây và thay thế LABEL_NAME bằng nhãn bạn chọn:

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

      Trong trường android:value, bạn có thể chỉ định một dải ô hoặc một tập hợp số nguyên từ 1 đến 1024 (số vòng lặp tối đa được phép cho một hoạt động kiểm thử) đại diện cho vòng lặp mà bạn muốn gắn nhãn. Xin lưu ý rằng các vòng lặp được lập chỉ mục bắt đầu từ 1, chứ không phải từ 0. Ví dụ: android:value="1,3-5" áp dụng LABEL_NAME cho vòng lặp 1, 3, 4 và 5.

    2. Trong ứng dụng Trình quản lý vòng lặp kiểm thử, hãy nhập một hoặc nhiều nhãn vào trường Nhãn.

  • Nếu bạn đang chạy một thử nghiệm bằng bảng điều khiển của Firebase, hãy nhập một hoặc nhiều nhãn vào trường Nhãn.

  • Nếu bạn đang chạy kiểm thử bằng Giao diện dòng lệnh (CLI) của gcloud, hãy chỉ định một hoặc nhiều nhãn tình huống bằng cách sử dụng cờ --scenario-labels (ví dụ: --scenario-labels=performance,gpu).

Hỗ trợ cấp phép ứng dụng

Phòng thử nghiệm hỗ trợ các ứng dụng dùng dịch vụ Cấp phép ứng dụng do Google Play cung cấp. Để kiểm tra thành công việc cấp phép khi kiểm thử ứng dụng bằng Phòng thử nghiệm, bạn phải xuất bản ứng dụng lên kênh phát hành chính thức trong Cửa hàng Play. Để kiểm thử ứng dụng của bạn trong kênh alpha hoặc beta bằng Phòng thử nghiệm, hãy xoá bước kiểm tra cấp phép trước khi tải ứng dụng lên Phòng thử nghiệm.

Các vấn đề đã biết

Việc kiểm thử Vòng lặp trò chơi trong Phòng thử nghiệm có các vấn đề đã biết sau đây:

  • Một số sự cố không hỗ trợ dấu vết ngược. Ví dụ: một số bản phát hành có thể chặn đầu ra của quy trình debuggerd bằng cách sử dụng prctl(PR_SET_DUMPABLE, 0). Để tìm hiểu thêm, hãy xem debuggerd.
  • API cấp 19 hiện không được hỗ trợ do lỗi về quyền truy cập tệp.