Pierwsze kroki z testami pętli gry

Automatyzacja testowania gier może być trudna, gdy aplikacje do gier są tworzone na podstawie różnych frameworków interfejsu użytkownika. Testy Game Loop umożliwiają integrację natywnych testów z Test Lab i łatwe ich uruchamianie na wybranych urządzeniach. Pętla gry testuje Twoją aplikację do gier, symulując działania prawdziwego gracza. Z tego przewodnika dowiesz się, jak uruchomić test Game Loop, a potem wyświetlić wyniki testu i nimi zarządzać w konsoli Firebase.

W zależności od silnika gry możesz wdrażać testy z jedną lub wieloma pętlami. Pętla to pełne lub częściowe przetestowanie aplikacji do gier. Pętli gier można używać do:

  • Uruchom poziom w grze w taki sam sposób, w jaki robi to użytkownik. Możesz albo stworzyć skrypt z danymi wejściowymi użytkownika, pozwolić mu na bezczynność lub zastąpić go AI, jeśli ma to sens w Twojej grze (np. jeśli masz aplikację do gier wyścigowych i już masz wdrożone AI). Możesz łatwo powierzyć sterowanie AI podając dane użytkownika).
  • Uruchom grę z najwyższą jakością, aby sprawdzić, czy urządzenia ją obsługują.
  • Przeprowadź test techniczny (skompiluj kilka shaderów, uruchom je, sprawdź, czy wynik jest zgodny z oczekiwaniami itp.).

Test pętli gry możesz przeprowadzić na jednym urządzeniu testowym, na 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ą częstotliwość klatek niż urządzenia fizyczne.

.

Zanim zaczniesz

Aby wdrożyć test, musisz najpierw skonfigurować aplikację na potrzeby testów pętli gry.

  1. W pliku manifestu aplikacji dodaj nowy filtr intencji do 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ę, wywołując ją za pomocą określonego zamiaru.

  2. W kodze (zalecamy w 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 aktywność może sprawdzić intencję, która ją uruchamia. Jeśli chcesz, możesz dodać ten kod później (np. po początkowym załadowaniu silnika gry).

  3. Zalecane: na końcu testu dodaj:

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    Spowoduje to zamknięcie aplikacji po zakończeniu testu pętli gry. Test korzysta z ramy UI aplikacji, aby rozpocząć następną pętlę, a jej zamknięcie sygnalizuje, że test się zakończył.

Tworzenie i przeprowadzanie testu pętli gry

Po skonfigurowaniu aplikacji do testów Game Loop możesz od razu utworzyć test i go uruchomić w aplikacji do gier. Możesz uruchomić test w Test Lab za pomocą konsoli Firebase lub interfejsu wiersza poleceń gcloud albo na lokalnym urządzeniu za pomocą menedżera Game Loop.

Uruchamianie na urządzeniu lokalnym

Menedżer testów Game Loop firmy Test Lab to aplikacja open source, która ułatwia integrację testów Game Loop i ich uruchamianie na urządzeniach lokalnych. Pozwala też 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 telefonie lub tablecie i zainstaluj go, uruchamiając:
    adb install testloopmanager.apk
  2. Na urządzeniu otwórz aplikację Test Loop Apps na telefonie lub tablecie. Aplikacja wyświetla listę aplikacji na urządzeniu, które można uruchamiać w pętli gry. Jeśli nie widzisz tu swojej aplikacji do gier, sprawdź, czy filtr intencji jest zgodny z tym opisanym w pierwszym kroku sekcji Zanim zaczniesz.
  3. Wybierz aplikację do gier, a potem 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 wykonowywaniu wielu pętli jednocześnie znajdziesz w artykule Opcjonalne funkcje.
  4. Kliknij Uruchom test. Test rozpocznie się od razu.

Uruchom w Test Lab

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

Korzystanie z konsoli Firebase

  1. W konsoli Firebase kliknij Test Lab w lewym panelu.
  2. Kliknij Uruchom pierwszy test (lub Uruchom test, jeśli test został już wcześniej przeprowadzony).
  3. Jako typ testu wybierz Game Loop, a potem 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 artykule Opcjonalne funkcje.
  5. Kliknij Dalej.
  6. Wybierz urządzenia fizyczne, których chcesz używać do testowania aplikacji.
  7. Kliknij Rozpocznij testy.

Więcej informacji o pierwszych krokach z konsolą Firebase znajdziesz w artykule Rozpoczęcie testowania w konsoli Firebase.

Korzystanie z interfejsu wiersza poleceń gcloud (CLI)

  1. Pobierz i zainstaluj pakiet Google Cloud SDK, jeśli jeszcze tego nie zrobiono.

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

    gcloud auth login

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

    gcloud config set project PROJECT_ID
    
  4. Przeprowadź 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 pierwszych krokach z interfejsem wiersza poleceń gcloud znajdziesz w artykule Rozpoczęcie testowania za pomocą wiersza poleceń gcloud.

Funkcje opcjonalne

Test Lab oferuje kilka opcjonalnych funkcji, które umożliwiają dalsze dostosowywanie testów, w tym zapisywanie danych wyjściowych, obsługę wielu pętli gry i etykietek 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 przeprowadzeniu testu możesz uzyskać dostęp do tych danych wyjściowych w sekcji Test Lab w konsoli Firebase (patrz Przykład pliku wyjściowego testu Game Loop).

Test Lab stosuje się do sprawdzonych metod udostępniania plików między aplikacjami opisanych w artykule Udostępnianie plików. W metodzie onCreate() aktywności, w której znajduje się Twój zamiar, możesz sprawdzić plik danych wyjściowych, uruchamiając ten 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 zapisać dane w pliku po stronie C++, 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

Pliki danych wyjściowych (sformatowane jak w przykładzie poniżej) możesz wykorzystać do wyświetlania wyników testu pętli w sekcji Test Lab konsoli Firebase. Obszary oznaczone jako /.../ mogą zawierać dowolne potrzebne 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żesz uruchomić w aplikacji kilka pętli gry. Pętla to pełne przejście przez grę od początku do końca. Jeśli na przykład masz w grze kilka poziomów, możesz użyć jednego pętli gry do uruchamiania każdego poziomu zamiast pętli, która przetwarza wszystkie poziomy. Dzięki temu, jeśli aplikacja ulegnie awarii na poziomie 32, możesz uruchomić ten poziom bezpośrednio, 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 testowej:

    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 podać liczbę całkowitą od 1 do 1024 (maksymalna liczba pętli dozwolonych w pojedynczym teście). Pamiętaj, ż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 kilka pętli, każda z nich będzie uruchamiana po kolei po zakończeniu poprzedniej.

  • Jeśli testujesz działanie za pomocą konsoli Firebase, w polu Scenariusze wpisz listę lub zakres liczby powtórzeń.

  • Jeśli testujesz za pomocą interfejsu wiersza poleceń gcloud, określ listę numerów pętli, używając flagi --scenario-numbers. Na przykład: --scenario-numbers=1,3,5 wykonuje pętle 1, 3 i 5.

  • Jeśli piszesz kod w C++ i chcesz zmienić działanie pętli, prześlij do kodu natywnego C++ te dodatkowe informacje:

    Kotlin+KTX

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

    Java

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

    Teraz możesz zmienić działanie pętli na podstawie otrzymanej wartości int.

Etykietowanie pętli gry

Gdy oznaczysz pętle gry co najmniej 1 etykietą scenariusza, Ty i Twój zespół ds.kontroli jakości będziecie mogli łatwo uruchomić zestaw powiązanych pętli gry (np. „wszystkie pętle zgodności z grą”) i przetestować je w ramach jednej matrycy. Możesz tworzyć własne etykiety lub używać wstępnie zdefiniowanych etykiet oferowanych przez Test Lab:

  • com.google.test.loops.player_experience: pętle używane do odtworzenia wrażeń prawdziwego użytkownika podczas grania w grę. Celem testowania za pomocą tych pętli jest znalezienie problemów, które mogą wystąpić w trakcie grania w grę przez prawdziwego użytkownika.
  • com.google.test.loops.gpu_compatibility: pętle for służące do testowania problemów związanych z kartą graficzną. Celem testowania za pomocą tych pętli jest wykonanie kodu GPU, który może nie działać prawidłowo w wersji produkcyjnej, aby wykryć problemy ze sprzętem i sterownikami.
  • com.google.test.loops.compatibility: do pętli używanych do testowania szerokiego zakresu problemów ze zgodnością, w tym problemów z wejściem i wyjściem oraz OpenSSL.
  • com.google.test.loops.performance: pętle for służące do testowania wydajności urządzenia. Na przykład gra może działać 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 przeprowadzasz test za pomocą Menedżera pętli testowej:

    1. W pliku manifestu aplikacji dodaj ten wiersz metadanych, zastępując 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 zbiór liczb całkowitych od 1 do 1024 (maksymalna liczba pętli dozwolonych w pojedynczym teście), które reprezentują pętle, do których chcesz dodać etykiety. Pamiętaj, że pętle są indeksowane od 1, a nie od 0. Na przykład reguła android:value="1,3-5" ma zastosowanie do pętli 1, 3, 4 i 5.LABEL_NAME

    2. W aplikacji Test Loop Manager wpisz co najmniej 1 etykietę w polu Etykiety.

  • Jeśli testujesz konsolę Firebase, wpisz co najmniej 1 etykietę w polu Etykiety.

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

Pomoc dotycząca licencjonowania aplikacji

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

Znane problemy

Testy Game Loop w Test Lab mają te znane problemy:

  • Niektóre awarie nie obsługują śledzenia. Na przykład niektóre wersje kompilacji mogą tłumić dane wyjściowe procesu debuggerd za pomocą parametru 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.