Zacznij od testów Game Loop

Zautomatyzowanie testowania gier może być trudne, jeśli aplikacje do gier są zbudowane na różnych platformach interfejsu użytkownika. Testy Game Loop pozwalają na integrację testów natywnych z Laboratorium Testowym i łatwe uruchamianie ich na wybranych urządzeniach. Test pętli gry przeprowadza test w aplikacji do gier, symulując działania prawdziwego gracza. W tym przewodniku dowiesz się, jak uruchomić test pętli gry, a następnie przeglądać wyniki testów i zarządzać nimi w konsoli Firebase.

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

  • Uruchom poziom swojej gry w taki sam sposób, w jaki grałby w nią użytkownik końcowy. Możesz albo napisać skrypt wprowadzający dane użytkownika, pozwolić mu być bezczynnym, albo zastąpić go sztuczną inteligencją, jeśli ma to sens w Twojej grze (np. załóżmy, że masz aplikację do gier wyścigowych i masz już zaimplementowaną sztuczną inteligencję. Możesz łatwo umieścić sterownik AI odpowiedzialny za wprowadzanie danych przez użytkownika).
  • Uruchom grę z najwyższym ustawieniem jakości, aby sprawdzić, czy urządzenia ją obsługują.
  • Uruchom test techniczny (skompiluj wiele shaderów, uruchom je, sprawdź, czy dane wyjściowe są zgodne z oczekiwaniami itp.).

Możesz uruchomić test Game Loop 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ę w porównaniu z urządzeniami fizycznymi.

Zanim zaczniesz

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

  1. W manifeście aplikacji dodaj do swojej aktywności nowy filtr intencji:

    <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 Laboratorium Testowe może uruchomić Twoją grę, uruchamiając ją w określonym celu.

  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. Jeśli wolisz, możesz także dodać ten kod później (np. po pierwszym 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 pętli gry. Test opiera się na strukturze interfejsu użytkownika aplikacji, aby rozpocząć następną pętlę, a zamknięcie aplikacji informuje ją o zakończeniu testu.

Utwórz i uruchom test pętli gry

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 laboratorium testowym, korzystając z konsoli Firebase , interfejsu wiersza poleceń gcloud (CLI) lub na urządzeniu lokalnym za pomocą Menedżera pętli testowej .

Uruchom na urządzeniu lokalnym

Menedżer pętli testowej firmy Test Lab to aplikacja typu open source, która pomaga integrować testy Game Loop i uruchamiać je na urządzeniach lokalnych. Umożliwia także Twojemu zespołowi ds. zapewnienia jakości uruchamianie tych samych pętli gier na swoich urządzeniach.

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

  1. Pobierz Menedżera pętli testowej 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 uruchomić z pętlami gier. 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 aplikację do gier, a następnie wybierz liczbę pętli, które chcesz uruchomić. Uwaga: na tym etapie możesz wybrać uruchomienie podzbioru pętli zamiast tylko jednej pętli. Aby uzyskać więcej informacji na temat jednoczesnego uruchamiania wielu pętli, zobacz Funkcje opcjonalne .
  4. Kliknij opcję Uruchom test . Twój test rozpoczyna się natychmiast.

Uruchom w laboratorium testowym

Test pętli gry możesz uruchomić w laboratorium testowym, korzystając z 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 Laboratorium testowe w lewym panelu.
  2. Kliknij opcję Uruchom swój pierwszy test (lub Uruchom test, jeśli w Twoim projekcie przeprowadzono już test).
  3. Jako typ testu wybierz opcję Game Loop , a następnie kliknij przycisk Kontynuuj .
  4. Kliknij Przeglądaj , a następnie przejdź do pliku .apk swojej aplikacji. Uwaga: na tym etapie możesz wybrać uruchomienie podzbioru pętli zamiast tylko jednej pętli. Aby uzyskać więcej informacji na temat jednoczesnego uruchamiania wielu pętli, zobacz Funkcje opcjonalne .
  5. Kliknij Kontynuuj .
  6. Wybierz urządzenia fizyczne, których chcesz użyć do przetestowania aplikacji.
  7. Kliknij opcję Rozpocznij testy .

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

Użyj wiersza poleceń gcloud (CLI)

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

  2. Zaloguj się do interfejsu wiersza polecenia gcloud 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
    

Aby uzyskać więcej informacji na temat rozpoczynania pracy z interfejsem wiersza polecenia gcloud, zobacz Rozpoczynanie testowania z wiersza poleceń gcloud.

Opcjonalne funkcje

Laboratorium testowe 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 powiązanych pętli.

Zapisz dane wyjściowe

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

Laboratorium testowe stosuje najlepsze praktyki dotyczące udostępniania pliku pomiędzy aplikacjami opisane w sekcji Udostępnianie pliku . W metodzie onCreate() Twojego działania, 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 do gry, możesz przekazać deskryptor pliku zamiast ścieżki 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 poniższym przykładzie), aby wyświetlić wyniki testu pętli gry w sekcji Laboratorium testowe konsoli Firebase. Obszary pokazane jako /.../ mogą zawierać dowolne potrzebne 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

Uruchamianie wielu pętli gry w aplikacji może okazać się przydatne. Pętla to kompletny przegląd aplikacji gry od początku do końca. Na przykład, jeśli w grze masz wiele poziomów, możesz chcieć mieć jedną pętlę gry do uruchamiania każdego poziomu, zamiast jednej pętli, która przechodzi przez wszystkie poziomy. W ten sposób, 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 przeprowadzasz test za pomocą Menedżera pętli testowej:

    1. Dodaj następujący wiersz do manifestu aplikacji wewnątrz elementu <application> :

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

      Ten zamiar uruchomienia zawiera pętlę docelową jako parametr całkowity. W polu android:value możesz podać liczbę całkowitą z zakresu od 1 do 1024 (maksymalna liczba pętli dozwolona w pojedynczym teście). Należy pamiętać, że pętle są indeksowane począwszy od 1, a nie od 0.

    2. W aplikacji Test Loop Manager pojawia się ekran wyboru, który umożliwia wybranie pętli, które chcesz uruchomić. Jeśli wybierzesz wiele pętli, każda pętla zostanie uruchomiona sekwencyjnie po zakończeniu poprzedniej pętli.

  • Jeśli przeprowadzasz test z konsolą Firebase, w polu Scenariusze wprowadź listę lub zakres numerów pętli.

  • Jeśli przeprowadzasz test za pomocą interfejsu 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 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 pętli w oparciu o wynikową wartość int .

Oznacz pętle gier

Kiedy oznaczysz swoje pętle gry jedną lub większą liczbą etykiet scenariuszy, Ty i Twój zespół ds. kontroli jakości możecie z łatwością uruchomić zestaw powiązanych pętli gier (np. „wszystkie pętle gier zgodności”) i przetestować je w pojedynczej macierzy. Możesz tworzyć własne etykiety lub skorzystać z gotowych etykiet oferowanych przez Laboratorium Testowe:

  • com.google.test.loops.player_experience : pętle używane do odtwarzania wrażeń prawdziwego użytkownika podczas gry. Celem testowania tych pętli jest znalezienie problemów, z którymi boryka się prawdziwy użytkownik podczas gry.
  • com.google.test.loops.gpu_compatibility : dla pętli używanych do testowania problemów związanych z procesorem graficznym. Celem testowania z użyciem tych pętli jest wykonanie kodu GPU, który może nie działać prawidłowo w środowisku produkcyjnym, w celu ujawnienia problemów 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 we/wy i problemów z OpenSSL.
  • com.google.test.loops.performance : pętle używane do testowania wydajności urządzenia. Na przykład gra może działać przy najbardziej złożonych ustawieniach graficznych, 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 manifeście aplikacji dodaj następujący 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 zbiór liczb całkowitych od 1 do 1024 (maksymalna liczba pętli dozwolona dla pojedynczego testu), które reprezentują pętle, które chcesz oznaczyć etykietą. 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 Test Loop Manager wprowadź jedną lub więcej etykiet w polu Etykiety .

  • Jeśli przeprowadzasz test z konsolą Firebase, wprowadź jedną lub więcej etykiet w polu Etykiety .

  • Jeśli uruchamiasz 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 w zakresie licencjonowania aplikacji

Laboratorium testowe obsługuje aplikacje korzystające z usługi licencjonowania aplikacji oferowanej przez Google Play. Aby pomyślnie sprawdzić licencję podczas testowania aplikacji w Test Lab, musisz opublikować swoją aplikację na kanale produkcyjnym w sklepie Play. Aby przetestować aplikację w kanale alfa lub beta za pomocą Laboratorium testowego, usuń kontrolę licencji przed przesłaniem aplikacji do laboratorium testowego.

Znane problemy

W testach pętli gry w laboratorium testowym występują następujące znane problemy:

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