获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

Zacznij od testów Game Loop na iOS

Dzięki testom w pętli gry możesz pisać testy natywne dla silnika gry, a następnie uruchamiać je w laboratorium testowym na wybranych przez siebie urządzeniach. W ten sposób nie musisz się martwić o pisanie dla różnych interfejsów użytkownika lub frameworków testowych. Test pętli gry symuluje działania prawdziwego gracza, a po uruchomieniu go w laboratorium testowym zapewnia szybki i skalowalny sposób sprawdzenia, czy gra działa dobrze dla użytkowników.

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

Co to jest test pętli gry?

Pętla to pełne lub częściowe wykonanie testu w aplikacji do gier. Test pętli gry można uruchomić lokalnie na symulatorze lub na zestawie urządzeń w laboratorium testowym. Testy pętli gry mogą służyć do:

  • Uruchom grę tak, jak grałby w nią użytkownik końcowy. Możesz albo oskryptować dane wprowadzone przez użytkownika, pozwolić mu być bezczynnym, albo zastąpić użytkownika sztuczną inteligencją (na przykład, jeśli zaimplementowałeś sztuczną inteligencję w grze wyścigowej, możesz umieścić kierowcę AI jako odpowiedzialnego za dane wejściowe użytkownika) .

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

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

Krok 1: Zarejestruj niestandardowy schemat adresu URL laboratorium Test Lab

Najpierw musisz zarejestrować w swojej aplikacji niestandardowy schemat adresów 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 również 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 testu przy użyciu laboratorium testowego.

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

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

W delegatze 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:).
  }
}

Po uruchomieniu wielu pętli w teście bieżąca pętla jest przekazywana jako parametr do adresu URL używanego do uruchamiania aplikacji. Numer bieżącej pętli można również uzyskać, 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 w Test Lab 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 (musisz 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 w konsoli Firebase kliknij Uruchom pierwszy test > Uruchom pętlę gry iOS .

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

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

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

  5. W sekcji Urządzenia wybierz co najmniej jedno urządzenie fizyczne, na którym chcesz przetestować swoją aplikację, a następnie kliknij Rozpocznij testy .

Przeprowadź test za pomocą interfejsu wiersza polecenia gcloud beta

  1. Skonfiguruj lokalne środowisko SDK gcloud, a następnie zainstaluj komponent gcloud beta .

  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 systemu iOS, który chcesz uruchomić. Możesz wprowadzić typy testów xctest (domyślne) lub game-loop .

--app

Wymagane : ścieżka bezwzględna (Google Cloud Storage lub system plików) do pliku IPA Twojej 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żesz wprowadzić jedną pętlę, listę lub pętle albo 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

Fizyczne urządzenie, na którym chcesz przeprowadzić test (dowiedz się, z jakich dostępnych urządzeń możesz korzystać).

--timeout

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

Na przykład:

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

Na przykład następujące polecenie uruchamia test Game Loop, 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 przeprowadzić test lokalnie, załaduj aplikację do gier w symulatorze i uruchom:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • Identyfikator UDID symulatora można znaleźć, uruchamiając polecenie instruments -s devices .

  • Jeśli działa tylko jeden symulator, wprowadź 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 uruchamiania testu lokalnie 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 kontynuuje działanie, dopóki nie przekroczy limitu czasu pięciu 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 firebase-game-loop-complete w usłudze AppDelegate aplikacji Test Lab. 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) {}];
}

Test pętli gry kończy bieżącą pętlę i wykonuje następną pętlę. Gdy nie ma więcej pętli do uruchomienia, test się kończy.

Napisz niestandardowe wyniki testów

Możesz skonfigurować test pętli gry, aby zapisywać niestandardowe wyniki testu w systemie plików urządzenia. W ten sposób, gdy test zacznie działać, Test Lab przechowuje pliki wyników w katalogu GameLoopsResults na twoim urządzeniu testowym (który musisz utworzyć samodzielnie). Po zakończeniu testu Test Lab przenosi wszystkie pliki z katalogu GameLoopResults do zasobnika projektu. Podczas konfigurowania testu pamiętaj o następujących kwestiach:

  • Wszystkie pliki wynikowe są przesyłane niezależnie od typu pliku, rozmiaru lub ilości.

  • Test Lab 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, które zapisują dane wyjściowe, upewnij się, że dołączasz je do unikalnego pliku wynikowego lub tworzysz plik wynikowy dla każdej pętli. W ten sposób możesz 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];
        }
    }