Zacznij od testów pętli gry

Zautomatyzowanie testowania gier może być trudne, gdy aplikacje do gier są zbudowane na różnych platformach interfejsu użytkownika. Testy Game Loop umożliwiają integrację testów natywnych z Test Lab i łatwe uruchamianie ich na wybranych urządzeniach. Test Game Loop przeprowadza test przez aplikację do gier, jednocześnie symulując działania prawdziwego gracza. Z tego przewodnika dowiesz się, jak przeprowadzić test Game Loop, a następnie wyświetlić wyniki testu i zarządzać nimi w konsoli Firebase.

W zależności od silnika gry możesz zaimplementować testy z pojedynczą lub wieloma pętlami . Pętla to pełne lub częściowe przejście testu w aplikacji do gier. Pętle gry mogą być używane do:

  • Uruchom poziom swojej gry w taki sam sposób, w jaki grałby w nią użytkownik końcowy. Możesz albo skryptować dane wejściowe użytkownika, pozwolić użytkownikowi być bezczynnym, albo zastąpić go sztuczną inteligencją, jeśli ma to sens w twojej grze (np. powiedzmy, że masz aplikację do gier wyścigowych i już zaimplementowaną sztuczną inteligencję. Możesz łatwo umieścić kierowcę AI odpowiedzialnego za dane wejściowe użytkownika).
  • Uruchom grę z najwyższą jakością, aby sprawdzić, czy urządzenia ją obsługują.
  • Uruchom test techniczny (skompiluj wiele shaderów, wykonaj je, sprawdź, czy dane wyjściowe są zgodne z oczekiwaniami itp.).

Możesz uruchomić test pętli gry na pojedynczym urządzeniu testowym, zestawie urządzeń testowych lub w laboratorium testowym. Nie zalecamy jednak przeprowadzania testów Game Loop na urządzeniach wirtualnych, ponieważ mają one niższą liczbę klatek na sekundę grafiki niż urządzenia fizyczne.

Zanim zaczniesz

Aby zaimplementować test, musisz najpierw skonfigurować aplikację do testów Game Loop.

  1. W manifeście 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ć twoją grę, uruchamiając ją z określonym zamiarem.

  2. W swoim kodzie (zalecamy wewnątrz deklaracji metody onCreate ) dodaj:

    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
    }

    Dzięki temu Twoja aktywność może sprawdzić intencję, która ją uruchamia. Możesz również dodać ten kod później, jeśli wolisz (np. po początkowym załadowaniu silnika gry).

  3. Zalecane: Na koniec testu dodaj:

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    Spowoduje to zamknięcie aplikacji po zakończeniu testu Game Loop. Test opiera się na strukturze interfejsu użytkownika Twojej aplikacji, aby rozpocząć następną pętlę, a zamknięcie aplikacji informuje ją, że test został zakończony.

Utwórz i uruchom test Game Loop

Po skonfigurowaniu aplikacji do testów Game Loop możesz od razu utworzyć test i uruchomić go w swojej aplikacji do gier. Możesz uruchomić test w Test Lab przy użyciu konsoli Firebase lub interfejsu wiersza poleceń gcloud (CLI) albo na urządzeniu lokalnym za pomocą Menedżera pętli testów .

Uruchom na urządzeniu lokalnym

Test Loop Manager firmy Test Lab to aplikacja typu open source, która pomaga integrować testy Game Loop i uruchamiać je na urządzeniach lokalnych. Pozwala również Twojemu zespołowi ds. zapewniania jakości uruchamiać te same pętle gry na swoich urządzeniach.

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

  1. Pobierz Test Loop Manager na telefon lub tablet i zainstaluj go, uruchamiając:
    adb install testloopmanager.apk
  2. Na swoim urządzeniu otwórz aplikację Test Loop Apps na telefonie lub tablecie. Aplikacja wyświetla listę aplikacji na Twoim urządzeniu, które można uruchamiać za pomocą pętli gry. Jeśli nie widzisz tutaj swojej aplikacji do gier, upewnij się, że filtr intencji odpowiada filtrowi opisanemu w pierwszym kroku sekcji Zanim zaczniesz .
  3. Wybierz swoją aplikację do gier, a następnie wybierz liczbę pętli, które chcesz uruchomić. Uwaga: W tym kroku możesz wybrać uruchomienie podzestawu pętli zamiast tylko jednej pętli. Aby uzyskać więcej informacji na temat uruchamiania wielu pętli jednocześnie, zobacz Funkcje opcjonalne.
  4. Kliknij Uruchom test . Twój test rozpocznie się natychmiast.

Uruchom w laboratorium testowym

Możesz uruchomić test Game Loop w Test Lab, używając konsoli Firebase lub interfejsu wiersza polecenia gcloud. Zanim zaczniesz, jeśli jeszcze tego nie zrobiłeś, otwórz konsolę Firebase i utwórz projekt.

Użyj konsoli Firebase

  1. W konsoli Firebase kliknij Test Lab w lewym panelu.
  2. Kliknij opcję Uruchom swój pierwszy test (lub Uruchom test, jeśli w projekcie przeprowadzono wcześniej test).
  3. Wybierz Game Loop jako typ testu, a następnie kliknij Kontynuuj .
  4. Kliknij Przeglądaj , a następnie przejdź do pliku .apk swojej aplikacji. Uwaga: W tym kroku możesz wybrać uruchomienie podzestawu pętli zamiast tylko jednej pętli. Aby uzyskać więcej informacji na temat uruchamiania wielu pętli jednocześnie, zobacz Funkcje opcjonalne.
  5. Kliknij Kontynuuj .
  6. Wybierz urządzenia fizyczne, których chcesz użyć do przetestowania aplikacji.
  7. Kliknij Rozpocznij testy .

Aby uzyskać więcej informacji na temat rozpoczynania pracy z konsolą Firebase, zobacz Rozpoczynanie testowania z konsolą Firebase.

Użyj wiersza polecenia gcloud (CLI)

  1. Jeśli jeszcze tego nie zrobiłeś, pobierz i zainstaluj Google Cloud SDK.

  2. Zaloguj się do gcloud CLI przy użyciu swojego konta Google:

    gcloud auth login

  3. Ustaw swój projekt Firebase w gcloud, gdzie PROJECT_ID to identyfikator twojego projektu Firebase:

    gcloud config set project PROJECT_ID
    
  4. Uruchom swój 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 interfejsem wiersza polecenia gcloud znajdziesz w artykule Rozpoczynanie testowania z wiersza poleceń gcloud.

Funkcje opcjonalne

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

Zapisz dane wyjściowe

Twój test Game Loop może zapisać dane wyjściowe do pliku określonego w metodzie launchIntent.getData() . Po przeprowadzeniu testu możesz uzyskać dostęp do tych danych wyjściowych w sekcji Test Lab konsoli Firebase (zobacz przykładowy plik wyjściowy testu Game Loop ).

Laboratorium testowe przestrzega sprawdzonych metod udostępniania pliku między aplikacjami opisanych w sekcji Udostępnianie pliku . W metodzie onCreate() Twojej aktywności, w której znajduje się Twoja intencja, możesz sprawdzić plik wyjściowy danych, uruchamiając następujący kod:

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

Jeśli chcesz pisać do pliku ze strony C++ swojej aplikacji gry, możesz przekazać deskryptor pliku zamiast ścieżki do pliku:

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

Przykład pliku wyjściowego

Możesz użyć plików danych wyjściowych (sformatowanych jak w przykładzie poniżej), aby wyświetlić wyniki testu pętli gry w sekcji Laboratorium testowe konsoli Firebase. Obszary pokazane jako /.../ mogą zawierać dowolne pola niestandardowe, o ile nie kolidują one z nazwami innych pól użytych 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

Uruchomienie wielu pętli gry w aplikacji może okazać się przydatne. Pętla to kompletne omówienie Twojej gry od początku do końca. Na przykład, jeśli masz wiele poziomów w swojej grze, możesz chcieć mieć jedną pętlę gry, aby uruchamiać każdy poziom, zamiast jednej pętli, która przechodzi przez wszystkie z nich. W ten sposób, jeśli Twoja 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 przeprowadzasz test za pomocą Menedżera pętli testów:

    1. Dodaj następujący wiersz do manifestu swojej aplikacji, wewnątrz elementu <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 podać liczbę całkowitą od 1 do 1024 (maksymalna liczba pętli dozwolona dla pojedynczego testu). Zauważ, że pętle są indeksowane od 1, a nie od 0.

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

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

  • Jeśli przeprowadzasz test z interfejsem wiersza polecenia gcloud, określ listę numerów pętli, używając 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 swojej pętli, przekaż następujący dodatek do swojego natywnego kodu C++:

    Kotlin+KTX

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

    Java

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

    Możesz teraz zmienić zachowanie swojej pętli na podstawie wynikowej wartości int .

Oznacz pętle gry

Gdy oznaczysz swoje pętle gry jedną lub kilkoma etykietami scenariusza, Ty i Twój zespół ds. kontroli jakości możecie łatwo uruchomić zestaw powiązanych pętli gry (np. „wszystkie pętle gier zgodności”) i przetestować je w jednej macierzy. Możesz tworzyć własne etykiety lub skorzystać z gotowych 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 z tymi pętlami jest znalezienie problemów, z którymi napotkałby prawdziwy użytkownik podczas gry.
  • com.google.test.loops.gpu_compatibility : dla pętli używanych do testowania problemów związanych z GPU. Celem testowania z tymi pętlami jest wykonanie kodu GPU, który może nie działać poprawnie w środowisku produkcyjnym, aby ujawnić problemy ze sprzętem i sterownikami.
  • com.google.test.loops.compatibility : dla pętli używanych do testowania szerokiego zakresu problemów ze zgodnością, w tym problemów z wejściami/wyjściami i problemami z OpenSSL.
  • com.google.test.loops.performance : dla pętli używanych do testowania wydajności urządzenia. Na przykład gra może działać z najbardziej złożonymi ustawieniami graficznymi, aby zobaczyć, jak zachowuje się nowe urządzenie.

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

  • Jeśli przeprowadzasz test za pomocą Menedżera pętli testów:

    1. W manifeście swojej aplikacji dodaj następujący wiersz metadanych i zastąp LABEL_NAME wybraną przez siebie 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ć. Zwróć uwagę, ż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 Test Loop Manager wprowadź jedną lub więcej etykiet w polu Etykiety .

  • Jeśli przeprowadzasz test za pomocą konsoli Firebase, wpisz co najmniej jedną etykietę w polu Etykiety .

  • Jeśli przeprowadzasz test za pomocą interfejsu wiersza polecenia gcloud, określ co najmniej jedną etykietę scenariusza, używając flagi --scenario-labels (np. --scenario-labels=performance,gpu ).

Wsparcie licencjonowania aplikacji

Test Lab obsługuje aplikacje korzystające z usługi licencjonowania aplikacji oferowanej przez Google Play. Aby pomyślnie sprawdzić licencje podczas testowania aplikacji w Test Lab, musisz opublikować ją w kanale produkcyjnym w Sklepie Play. Aby przetestować aplikację w kanale alfa lub beta za pomocą Test Lab, usuń sprawdzanie licencji przed przesłaniem aplikacji do Test Lab.

Znane problemy

Testy Game Loop w Test Lab mają następujące znane problemy:

  • Niektóre awarie nie obsługują śledzenia wstecznego. Na przykład niektóre kompilacje wersji mogą pomijać dane wyjściowe procesu debuggerd przy użyciu prctl(PR_SET_DUMPABLE, 0) . Aby dowiedzieć się więcej, zobacz debuggerd .
  • Interfejs API poziomu 19 nie jest obecnie obsługiwany z powodu błędów uprawnień do plików.