Zacznij od testów Game Loop dla iOS

Dzięki testom Game Loop możesz pisać testy natywne dla silnika gry, a następnie uruchamiać je w laboratorium testowym na wybranych urządzeniach. W ten sposób nie musisz się martwić pisaniem dla różnych interfejsów użytkownika ani frameworkami testowymi. Test Game Loop symuluje działania prawdziwego gracza, a po uruchomieniu w laboratorium testowym zapewnia szybki i skalowalny sposób sprawdzenia, czy gra dobrze działa dla użytkowników.

Na tej stronie pokazano, jak uruchomić test pętli gry, a następnie przeglądać wyniki testów i zarządzać nimi na stronie Laboratorium testowe w konsoli Firebase. Możesz także dodatkowo dostosować swoje testy za pomocą opcjonalnych funkcji, takich jak zapisywanie niestandardowych wyników testów lub wcześniejsze zakończenie testu .

Co to jest test pętli gry?

Pętla to pełne lub częściowe wykonanie testu w aplikacji do gier. Możesz uruchomić test Game Loop lokalnie na symulatorze lub na zestawie urządzeń w laboratorium testowym. Testy pętli gry można wykorzystać do:

  • Uruchom grę tak, jak zrobiłby to użytkownik końcowy. Możesz albo napisać skrypt wprowadzający dane użytkownika, pozwolić mu być bezczynnym, albo zastąpić go sztuczną inteligencją (na przykład, jeśli zaimplementowałeś sztuczną inteligencję w grze wyścigowej, możesz wyznaczyć sterownik AI odpowiedzialny za wprowadzanie danych przez użytkownika) .

  • Uruchom grę w najwyższych ustawieniach jakości, aby dowiedzieć się, które urządzenia ją obsługują.

  • Uruchom test techniczny, taki jak kompilacja wielu shaderów, wykonanie ich i sprawdzenie, czy dane wyjściowe są zgodne z oczekiwaniami.

Krok 1: Zarejestruj niestandardowy schemat adresu URL laboratorium testowego

Najpierw musisz zarejestrować w swojej aplikacji niestandardowy schemat adresu URL Firebase Test Lab:

  1. W Xcode wybierz cel projektu.

  2. Kliknij kartę Informacje , a następnie dodaj nowy typ adresu URL .

  3. W polu Schematy adresów URL wpisz firebase-game-loop . Możesz także zarejestrować niestandardowy schemat adresu URL, dodając go do pliku konfiguracyjnego Info.plist projektu w dowolnym miejscu w tagu <dict> :

    <key>CFBundleURLTypes</key>
     <array>
         <dict>
             <key>CFBundleURLName</key>
             <string></string>
             <key>CFBundleTypeRole</key>
             <string>Editor</string>
             <key>CFBundleURLSchemes</key>
             <array>
                 <string>firebase-game-loop</string>
             </array>
         </dict>
     </array>
    

Twoja aplikacja jest teraz skonfigurowana do przeprowadzania testów w laboratorium testowym.

Krok 2 (opcjonalnie): Skonfiguruj aplikację do uruchamiania wielu pętli

Jeśli w aplikacji zarejestrowanych jest wiele niestandardowych schematów adresów URL i planujesz uruchomić w teście wiele pętli (tzw. scenariuszy), musisz określić, które pętle mają być uruchamiane w aplikacji w momencie jej uruchamiania.

W delegacie aplikacji zastąp metodę application(_:open:options:) :

Szybki

func application(_app: UIApplication,
                 open url: URL
                 options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
    if components.scheme == "firebase-game-loop" {
        // ...Enter Game Loop Test logic to override application(_:open:options:).
    }
    return true
}

Cel C

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary &lt;UIApplicationOpenURLOptionsKey, id&gt; *)options {
  if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
      // ...Enter Game Loop Test logic to override application(_:open:options:).
  }
}

Jeśli w teście uruchomisz wiele pętli, bieżąca pętla jest przekazywana jako parametr do adresu URL używanego do uruchamiania aplikacji. Możesz także uzyskać numer bieżącej pętli, analizując obiekt URLComponents używany do pobrania niestandardowego schematu adresu URL:

Szybki

if components.scheme == "firebase-game-loop" {
    // Iterate over all parameters and find the one with the key "scenario".
    let scenarioNum = Int(components.queryItems!.first(where: { $0.name == "scenario" })!.value!)!
    // ...Write logic specific to the current loop (scenarioNum).
}

Cel C

if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
    // Launch the app as part of a game loop.
    NSURLComponents *components = [NSURLComponents componentsWithURL:url
                                             resolvingAgainstBaseURL:YES];
    for (NSURLQueryItem *item in [components queryItems]) {
        if ([item.name isEqualToString:@"scenario"]) {
            NSInteger scenarioNum = [item.value integerValue];
            // ...Write logic specific to the current loop (scenarioNum).
        }
    }
}

Krok 3: Utwórz i uruchom test

Po zarejestrowaniu niestandardowego schematu adresu URL laboratorium testowego możesz uruchomić test w konsoli Firebase lub za pomocą interfejsu wiersza polecenia gcloud beta . Jeśli jeszcze tego nie zrobiłeś, wygeneruj plik IPA dla swojej aplikacji (będziesz musiał go później zlokalizować).

Uruchom test w konsoli Firebase

  1. Jeśli jeszcze tego nie zrobiłeś, otwórz konsolę Firebase i utwórz projekt.

  2. Na stronie Laboratorium testowe konsoli Firebase kliknij opcję Uruchom swój pierwszy test > Uruchom pętlę gry na iOS .

  3. W sekcji Prześlij aplikację kliknij Przeglądaj , a następnie wybierz plik IPA swojej aplikacji (jeśli jeszcze tego nie zrobiłeś, wygeneruj plik IPA dla swojej aplikacji).

  4. Opcjonalnie : jeśli chcesz uruchomić wiele pętli (tzw. scenariuszy) jednocześnie lub wybrać określone pętle do uruchomienia, wprowadź numery pętli w polu Scenariusze .

    Na przykład, jeśli wpiszesz „1-3, 5”, laboratorium testowe uruchomi pętle 1, 2, 3 i 5. Domyślnie (jeśli nie wpiszesz niczego w polu Scenariusze ), laboratorium testowe uruchomi tylko pętlę 1.

  5. W sekcji Urządzenia wybierz jedno lub więcej urządzeń fizycznych, na których chcesz przetestować aplikację, a następnie kliknij Rozpocznij testy .

Uruchom test za pomocą interfejsu wiersza polecenia gcloud beta

  1. Jeśli jeszcze tego nie zrobiłeś, skonfiguruj lokalne środowisko SDK gcloud, a następnie pamiętaj o zainstalowaniu komponentu beta gcloud .

  2. Uruchom polecenie gcloud beta firebase test ios run i użyj następujących flag, aby skonfigurować uruchomienie:

Flagi do testów pętli gry
--type

Wymagane : określa typ testu iOS, który chcesz uruchomić. Możesz wprowadzić typy testów xctest (domyślnie) lub game-loop .

--app

Wymagane : bezwzględna ścieżka (Google Cloud Storage lub system plików) do pliku IPA aplikacji. Ta flaga jest ważna tylko podczas uruchamiania testów Game Loop.

--scenario-numbers

Pętle (inaczej scenariusze), które chcesz uruchomić w swojej aplikacji. Można wprowadzić jedną pętlę, listę lub pętle lub zakres pętli. Domyślna pętla to 1.

Na przykład --scenario-numbers=1-3,5 uruchamia pętle 1, 2, 3 i 5.

--device-model

Urządzenie fizyczne, na którym chcesz uruchomić test (dowiedz się, z jakich dostępnych urządzeń możesz skorzystać).

--timeout

Maksymalny czas trwania testu. Można wprowadzić liczbę całkowitą, aby przedstawić czas trwania w sekundach, lub liczbę całkowitą i wyliczenie, aby przedstawić czas trwania jako dłuższą jednostkę czasu.

Na przykład:

  • --timeout=200 wymusza zakończenie testu po upływie do 200 sekund.
  • --timeout=1h wymusza zakończenie testu, gdy upłynie godzina.

Na przykład następujące polecenie uruchamia test pętli gry, który wykonuje pętle 1, 4, 6, 7 i 8 na telefonie iPhone 8 Plus:

gcloud beta firebase test ios run
 --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8
 --device-model=iphone8plus

Więcej informacji na temat interfejsu wiersza polecenia gcloud znajdziesz w dokumentacji referencyjnej .

Uruchom test lokalnie

Aby uruchomić test lokalnie, załaduj aplikację do gry w symulatorze i uruchom:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • Możesz znaleźć identyfikator UDID swojego symulatora, uruchamiając polecenie instruments -s devices .

  • Jeśli działa tylko jeden symulator, wpisz specjalny ciąg "booted" zamiast SIMULATOR_UDID .

Jeśli test zawiera wiele pętli, możesz określić, którą pętlę chcesz uruchomić, przekazując numer pętli do flagi scenario . Pamiętaj, że podczas lokalnego uruchamiania testu możesz uruchomić tylko jedną pętlę na raz. Na przykład, jeśli chcesz uruchomić pętle 1, 2 i 5, musisz uruchomić osobne polecenie dla każdej pętli:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=1
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5

Zakończ test wcześniej

Domyślnie test pętli gry jest kontynuowany aż do osiągnięcia limitu czasu wynoszącego pięć minut, nawet jeśli wszystkie pętle zostały wykonane. Po osiągnięciu limitu czasu test kończy się i anuluje wszystkie oczekujące pętle. Możesz przyspieszyć test lub zakończyć go wcześniej, wywołując niestandardowy schemat adresu URL laboratorium testowego firebase-game-loop-complete w AppDelegate swojej aplikacji. Na przykład:

Szybki

/// End the loop by calling our custom url scheme.
func finishLoop() {
    let url = URL(string: "firebase-game-loop-complete://")!
    UIApplication.shared.open(url)
}

Cel C

- (void)finishLoop {
  UIApplication *app = [UIApplication sharedApplication];
  [app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
      options:@{}
completionHandler:^(BOOL success) {}];
}

Twój test pętli gry kończy bieżącą pętlę i wykonuje następną pętlę. Gdy nie ma już żadnych pętli do wykonania, test się kończy.

Zapisz niestandardowe wyniki testów

Możesz skonfigurować test Game Loop, aby zapisywał niestandardowe wyniki testu w systemie plików swojego urządzenia. W ten sposób po rozpoczęciu testu Laboratorium Testowe przechowuje pliki wynikowe w katalogu GameLoopsResults na Twoim urządzeniu testowym (który musisz samodzielnie utworzyć). Po zakończeniu testu Laboratorium testowe przenosi wszystkie pliki z katalogu GameLoopResults do zasobnika Twojego projektu. Konfigurując test, pamiętaj o następujących kwestiach:

  • Przesyłane są wszystkie pliki wynikowe niezależnie od typu pliku, rozmiaru i ilości.

  • Laboratorium testowe nie przetwarza wyników testu, dopóki wszystkie pętle w teście nie zostaną uruchomione, więc jeśli test zawiera wiele pętli zapisujących dane wyjściowe, pamiętaj o dołączeniu ich do unikalnego pliku wynikowego lub utworzeniu pliku wynikowego dla każdej pętli. W ten sposób można uniknąć nadpisywania wyników z poprzedniej pętli.

Aby skonfigurować test do zapisywania niestandardowych wyników testu:

  1. W katalogu Documents aplikacji utwórz katalog o nazwie GameLoopResults .

  2. Z dowolnego miejsca w kodzie aplikacji (np. delegata aplikacji) dodaj następujące elementy:

    Szybki

    /// Write to a results file.
    func writeResults() {
      let text = "Greetings from game loops!"
      let fileName = "results.txt"
      let fileManager = FileManager.default
      do {
    
      let docs = try fileManager.url(for: .documentDirectory,
                                     in: .userDomainMask,
                                     appropriateFor: nil,
                                     create: true)
      let resultsDir = docs.appendingPathComponent("GameLoopResults")
      try fileManager.createDirectory(
          at: resultsDir,
          withIntermediateDirectories: true,
          attributes: nil)
      let fileURL = resultsDir.appendingPathComponent(fileName)
      try text.write(to: fileURL, atomically: false, encoding: .utf8)
      } catch {
        // ...Handle error writing to file.
      }
    }
    

    Cel C

    /// Write to a results file.
    - (void)writeResults:(NSString *)message {
        // Locate and create the results directory (if it doesn't exist already).
        NSFileManager *manager = [NSFileManager defaultManager];
        NSURL* url = [[manager URLsForDirectory:NSDocumentDirectory
                                      inDomains:NSUserDomainMask] lastObject];
        NSURL* resultsDir = [url URLByAppendingPathComponent:@"GameLoopResults"
                                                 isDirectory:YES];
        [manager createDirectoryAtURL:resultsDir
          withIntermediateDirectories:NO
                           attributes:nil
                                error:nil];
    
        // Write the result message to a text file.
        NSURL* resultFile = [resultsDir URLByAppendingPathComponent:@"result.txt"];
        if ([manager fileExistsAtPath:[resultFile path]]) {
            // Append to the existing file
            NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:resultFile
                                                                     error:nil];
            [handle seekToEndOfFile];
            [handle writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
            [handle closeFile];
        } else {
            // Create and write to the file.
            [message writeToURL:resultFile
                     atomically:NO
                       encoding:NSUTF8StringEncoding error:nil];
        }
    }