Pierwsze kroki z testami pętli gry

Automatyzacja testowania gier może być trudna, gdy aplikacje do gier są tworzone na różnych platformach interfejsu. Testy pętli gry umożliwiają zintegrowanie testów natywnych z Test Lab i łatwe uruchamianie ich na wybranych urządzeniach. Test pętli gry uruchamia test w aplikacji do gier, symulując działania prawdziwego gracza. Z tego przewodnika dowiesz się, jak przeprowadzić test pętli gry, a następnie wyświetlić wyniki testu i zarządzać nimi w Firebase konsoli.

W zależności od silnika gry możesz zaimplementować testy z jedną lub kilkoma pętlami. Pętla to pełne lub częściowe wykonanie testu w aplikacji do gier. Pętle gry można wykorzystać do:

  • uruchomienia poziomu gry w taki sam sposób, w jaki zrobiłby to użytkownik; możesz napisać skrypt wprowadzania danych przez użytkownika, pozwolić mu na bezczynność lub zastąpić go sztuczną inteligencją, jeśli ma to sens w Twojej grze (np. jeśli masz aplikację do wyścigów samochodowych i zaimplementowaną sztuczną inteligencję); możesz łatwo powierzyć sterowanie sztucznej inteligencji;
  • uruchomienia gry w najwyższej jakości, aby sprawdzić, czy urządzenia ją obsługują;
  • przeprowadzenia testu technicznego (skompilowania wielu shaderów, ich wykonania, sprawdzenia, czy dane wyjściowe są zgodne z oczekiwaniami itp.).

Test pętli gry możesz przeprowadzić na jednym urządzeniu testowym, zestawie urządzeń testowych lub na Test Lab. Nie zalecamy jednak przeprowadzania testów pętli gry na urządzeniach wirtualnych, ponieważ mają one niższą liczbę klatek na sekundę niż urządzenia fizyczne.

Zanim zaczniesz

Aby zaimplementować test, musisz najpierw skonfigurować aplikację pod kątem testów pętli gry.

  1. W pliku manifestu aplikacji dodaj nowy filtr intencji do swojej aktywności:

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

    Dzięki temu Test Lab może uruchomić grę, wywołując ją za pomocą określonej intencji.

  2. W kodzie (zalecamy dodanie go w deklaracji metody onCreate) dodaj ten kod:

    Kotlin

    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
    }

    Dzięki temu aktywność może sprawdzić intencję, która ją uruchamia. Jeśli wolisz, możesz też dodać ten kod później (np. po początkowym wczytaniu silnika gry).

  3. Zalecane: na końcu testu dodaj:

    Kotlin

    yourActivity.finish()

    Java

    yourActivity.finish();

    Po zakończeniu testu pętli gry aplikacja zostanie zamknięta. Test polega na tym, że platforma interfejsu aplikacji uruchamia następną pętlę, a zamknięcie aplikacji informuje ją o zakończeniu testu.

Tworzenie i uruchamianie testu pętli gry

Po skonfigurowaniu aplikacji pod kątem testów pętli gry możesz od razu utworzyć test i uruchomić go w aplikacji do gier. Możesz przeprowadzić test w Test Lab za pomocą konsoli Firebase lub interfejsu wiersza poleceń gcloud (CLI), albo na urządzeniu lokalnym za pomocą Menedżera pętli testowych.

Uruchamianie na urządzeniu lokalnym

Test Lab Laboratorium testów Menedżer pętli testowych to aplikacja open source, która pomaga zintegrować testy pętli gry i uruchamiać je na urządzeniach lokalnych. Umożliwia też zespołowi ds. kontroli jakości uruchamianie tych samych pętli gry na swoich urządzeniach.

Aby uruchomić test na urządzeniu lokalnym za pomocą Menedżera pętli testowych:

  1. Pobierz Menedżera pętli testowych na telefon lub tablet i zainstaluj go, uruchamiając to polecenie:
    adb install testloopmanager.apk
  2. Na urządzeniu otwórz aplikację Test Loop Apps. Aplikacja wyświetla listę aplikacji na urządzeniu, które można uruchomić za pomocą pętli gry. Jeśli nie widzisz tutaj swojej aplikacji do gier, upewnij się, że filtr intencji jest zgodny z filtrem opisanym w pierwszym kroku sekcji Zanim zaczniesz.
  3. Wybierz aplikację do gier, a następnie liczbę pętli, które chcesz uruchomić. Uwaga: na tym etapie możesz uruchomić podzbiór pętli zamiast tylko jednej pętli. Więcej informacji o uruchamianiu wielu pętli jednocześnie znajdziesz w sekcji Funkcje opcjonalne.
  4. Kliknij Uruchom test. Test rozpocznie się natychmiast.

Uruchamianie w Test Lab

Test pętli gry możesz uruchomić w Test Lab za pomocą Firebase konsoli lub interfejsu wiersza poleceń gcloud. Zanim zaczniesz, otwórz konsolę Firebase i utwórz projekt.

Korzystanie z konsoli Firebase

  1. W konsoli Firebase w panelu po lewej stronie kliknij Test Lab.
  2. Kliknij Uruchom pierwszy test (lub Uruchom test , jeśli w projekcie przeprowadzono już test).
  3. Jako typ testu wybierz Pętla gry, a następnie kliknij Dalej.
  4. Kliknij Przeglądaj, a następnie przejdź do pliku .apk aplikacji. Uwaga: na tym etapie możesz uruchomić podzbiór pętli zamiast tylko jednej pętli. Więcej informacji o uruchamianiu wielu pętli jednocześnie znajdziesz w sekcji Funkcje opcjonalne.
  5. Kliknij Dalej.
  6. Wybierz urządzenia fizyczne, na których chcesz przetestować aplikację.
  7. Kliknij Rozpocznij testy.

Więcej informacji o rozpoczynaniu pracy z konsolą Firebase znajdziesz w artykule Rozpoczynanie testowania za pomocą konsoli Firebase.

Korzystanie z interfejsu wiersza poleceń gcloud

  1. Jeśli jeszcze tego nie zrobisz, pobierz i zainstaluj pakiet Google Cloud SDK.

  2. Zaloguj się w gcloud CLI za pomocą konta Google:

    gcloud auth login

  3. Ustaw projekt Firebase w gcloud, gdzie PROJECT_ID to identyfikator projektu Firebase:

    gcloud config set project PROJECT_ID
    
  4. Uruchom pierwszy test:

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

Więcej informacji o rozpoczynaniu pracy z gcloud CLI znajdziesz w artykule Rozpoczynanie testowania z wiersza poleceń gcloud.

Funkcje opcjonalne

Test Lab oferuje kilka funkcji opcjonalnych, które umożliwiają dalsze dostosowywanie testów, w tym możliwość zapisywania danych wyjściowych, obsługę wielu pętli gry i etykiet dla powiązanych pętli.

Zapisywanie danych wyjściowych

Test pętli gry może zapisywać dane wyjściowe w pliku określonym w metodzie launchIntent.getData(). Po uruchomieniu testu możesz uzyskać dostęp do tych danych wyjściowych w sekcji Test Lab w konsoli Firebase (zobacz przykład pliku wyjściowego testu pętli gry).

Test Lab stosuje sprawdzone metody udostępniania pliku między aplikacjami opisane w Udostępnianie pliku. W metodzie onCreate() aktywności, w której znajduje się intencja, możesz sprawdzić plik danych wyjściowych, uruchamiając ten kod:

Kotlin

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

Jeśli chcesz zapisywać dane w pliku po stronie C++ aplikacji do gier, możesz przekazać deskryptor pliku zamiast ścieżki do pliku:

Kotlin

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

Przykład pliku wyjściowego

Pliki danych wyjściowych (sformatowane jak w przykładzie poniżej) możesz używać do wyświetlania wyników testów pętli gry w sekcji Test Lab w konsoli Firebase. Obszary oznaczone jako /.../ mogą zawierać dowolne pola niestandardowe, o ile nie kolidują z nazwami innych pól używanych w tym pliku:

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

Wiele pętli gry

Może się okazać, że warto uruchomić w aplikacji kilka pętli gry. Pętla to pełne wykonanie aplikacji do gier od początku do końca. Jeśli na przykład w grze jest kilka poziomów, możesz utworzyć jedną pętlę gry, która będzie uruchamiać każdy poziom, zamiast jednej pętli, która będzie przechodzić przez wszystkie poziomy. Dzięki temu, jeśli aplikacja ulegnie awarii na poziomie 32, możesz bezpośrednio uruchomić tę pętlę gry, aby odtworzyć awarię i przetestować poprawki błędów.

Aby umożliwić aplikacji uruchamianie wielu pętli jednocześnie:

  • Jeśli uruchamiasz test za pomocą Menedżera pętli testowych:

    1. Dodaj ten wiersz do pliku manifestu aplikacji w elemencie <application>:

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

      Ta intencja uruchomienia zawiera pętlę docelową jako parametr całkowity. W polu android:value możesz określić liczbę całkowitą od 1 do 1024 (maksymalna liczba pętli dozwolona w jednym teście). Pamiętaj, że pętle są indeksowane od 1, a nie od 0.

    2. W aplikacji Menedżer pętli testowych pojawi się ekran wyboru, na którym możesz wybrać pętle, które chcesz uruchomić. Jeśli wybierzesz kilka pętli, każda pętla zostanie uruchomiona po zakończeniu poprzedniej.

  • Jeśli uruchamiasz test za pomocą konsoli Firebase, w polu Scenariusze wpisz listę lub zakres numerów pętli.

  • Jeśli uruchamiasz test za pomocą gcloud CLI, określ listę numerów pętli za pomocą flagi --scenario-numbers. Na przykład --scenario-numbers=1,3,5 uruchamia pętle 1, 3 i 5.

  • Jeśli piszesz w C++ i chcesz zmienić zachowanie pętli, przekaż ten dodatkowy kod do natywnego kodu C++:

    Kotlin

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

    Java

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

    Teraz możesz zmienić zachowanie pętli na podstawie uzyskanej wartości int.

Etykietowanie pętli gry

Gdy oznaczysz pętle gry jedną lub kilkoma etykietami scenariuszy, Ty i Twój zespół ds.kontroli jakości możecie łatwo uruchomić zestaw powiązanych pętli gry (np. „wszystkie pętle gry dotyczące zgodności”) i przetestować je w jednej macierzy. Możesz tworzyć własne etykiety lub używać predefiniowanych etykiet oferowanych przez Test Lab:

  • com.google.test.loops.player_experience: pętle używane do odtwarzania wrażeń prawdziwego użytkownika podczas gry. Celem testowania za pomocą tych pętli jest znalezienie problemów, z którymi może się spotkać prawdziwy użytkownik podczas gry.
  • com.google.test.loops.gpu_compatibility: pętle używane do testowania problemów związanych z GPU. Celem testowania za pomocą tych pętli jest wykonanie kodu GPU, który może nie działać prawidłowo w środowisku produkcyjnym, aby wykryć problemy ze sprzętem i sterownikami.
  • com.google.test.loops.compatibility: pętle używane do testowania szerokiego zakresu problemów ze zgodnością, w tym problemów z wejściem/wyjściem i OpenSSL.
  • com.google.test.loops.performance: pętle używane do testowania wydajności urządzenia. Na przykład gra może być uruchamiana z najbardziej złożonymi ustawieniami grafiki, aby sprawdzić, jak zachowuje się nowe urządzenie.

Aby umożliwić aplikacji uruchamianie pętli z tą samą etykietą:

  • Jeśli uruchamiasz test za pomocą Menedżera pętli testowych:

    1. W pliku manifestu aplikacji dodaj ten wiersz metadanych i zastąp LABEL_NAME wybraną etykietą:

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

      W polu android:value możesz określić zakres lub zestaw liczb całkowitych od 1 do 1024 (maksymalna liczba pętli dozwolona w jednym teście), które reprezentują pętle, które chcesz oznaczyć. Pamiętaj, że pętle są indeksowane od 1, a nie od 0. Na przykład android:value="1,3-5" stosuje LABEL_NAME do pętli 1, 3, 4 i 5.

    2. W aplikacji Menedżer pętli testowych w polu Etykiety wpisz jedną lub więcej etykiet.

  • Jeśli uruchamiasz test za pomocą konsoli Firebase, w polu Etykiety wpisz jedną lub więcej etykiet.

  • Jeśli uruchamiasz test za pomocą gcloud CLI, określ jedną lub więcej etykiet scenariuszy za pomocą --scenario-labels flagi (np. --scenario-labels=performance,gpu).

Obsługa licencjonowania aplikacji

Test Lab obsługuje aplikacje, które korzystają z usługi licencjonowania aplikacji oferowanej przez Google Play. Aby podczas testowania aplikacji w Test Labmożna było sprawdzić licencję, musisz opublikować aplikację w kanale produkcyjnym w Sklepie Play. Aby przetestować aplikację w kanale alfa lub beta za pomocą Test Lab, przed przesłaniem aplikacji do Test Lab usuń sprawdzanie licencji.

Znane problemy

Znane problemy z testami pętli gry w Test Lab:

  • Niektóre awarie nie obsługują śledzenia wstecznego. Na przykład niektóre kompilacje wersji mogą pomijać dane wyjściowe procesu debuggerd za pomocą prctl(PR_SET_DUMPABLE, 0). Więcej informacji znajdziesz w artykule debuggerd.
  • Poziom interfejsu API 19 nie jest obecnie obsługiwany z powodu błędów uprawnień do plików.