Pierwsze kroki z testami pętli gry na iOS

Dzięki testom Game Loop możesz pisać testy natywne dla silnika gry, a potem uruchamiać je w Test Lab na wybranych urządzeniach. Dzięki temu nie musisz się martwić o tworzenie kodu dla różnych interfejsów użytkownika ani testowania w ramach. Test pętli gry symuluje działania prawdziwego gracza, a po uruchomieniu w Test Lab pozwala na szybkie i skalowalne sprawdzenie, czy gra działa dobrze dla użytkowników.

Na tej stronie dowiesz się, jak uruchomić test Game Loop, a potem wyświetlić wyniki testu i nimi zarządzać na stronie Test Lab w konsoli Firebase. Możesz też dodatkowo dostosować testy za pomocą opcjonalnych funkcji, takich jak zapisywanie niestandardowych wyników testu lub przedwczesne zakończenie testu.

Co to jest test pętli gry?

Pętla to pełne lub częściowe przetestowanie aplikacji do gier. Możesz przeprowadzić test pętli gry lokalnie na symulatorze lub na zestawie urządzeń w Test Lab. Testy pętli gry umożliwiają:

  • Rozegraj grę tak, jak grałby w nią użytkownik. Możesz albo stworzyć skrypt z danymi wejściowymi użytkownika, albo pozwolić, aby użytkownik był nieaktywny, albo zastąpić go sztuczną inteligencją (na przykład jeśli wdrożyłeś sztuczną inteligencję w grze wyścigowej, możesz ustawić sterowanie pojazdem na komputerze).

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

  • Przeprowadź test techniczny, na przykład skompiluj kilka shaderów, uruchom je i sprawdź, czy wyniki są zgodne z oczekiwaniami.

Krok 1. Zarejestruj niestandardowy schemat adresu URL Test Lab

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

  1. W Xcode wybierz ustawienie projektu.

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

  3. W polu Schematy URL wpisz firebase-game-loop. Możesz też 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>
    

Aplikacja jest teraz skonfigurowana do uruchamiania testów przy użyciu narzędzia Test Lab.

Krok 2 (opcjonalnie): skonfiguruj aplikację tak, aby wykonywała kilka pętli

Jeśli w Twojej aplikacji jest zarejestrowanych kilka niestandardowych schematów adresów URL, a zamierzasz przeprowadzić test z użyciem wielu pętli (czyli scenariuszy), musisz określić, które pętle mają być uruchamiane w aplikacji w momencie jej uruchomienia.

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

Swift

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
}

Objective-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 występuje kilka pętli, bieżąca pętla jest przekazywana jako parametr do adresu URL używanego do uruchamiania aplikacji. Bieżący numer pętli możesz też uzyskać, analizując obiekt URLComponents, który służy do pobierania niestandardowego schematu URL:

Swift

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

Objective-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 adresów URL usługi Test Lab możesz uruchomić test w konsoli Firebase lub za pomocą interfejsu wiersza poleceń gcloud w wersji beta. Wygeneruj plik IPA dla swojej aplikacji (będziesz go później potrzebować).

.

Uruchamianie testu w konsoli Firebase

  1. Jeśli nie masz jeszcze projektu, otwórz konsolę Firebase i utwórz projekt.

  2. Na stronie Test Lab w konsoli Firebase kliknij Przeprowadź pierwszy test > Uruchom pętlę gry na iOS.

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

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

    Jeśli na przykład wpiszesz „1-3, 5”, Test Lab wykona pętle 1, 2, 3 i 5. Domyślnie (jeśli w polu Scenariusze nic nie wpiszesz) Test Lab uruchamia się tylko pętla 1.

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

Przeprowadzanie testu za pomocą interfejsu wiersza poleceń gcloud w wersji beta

  1. Skonfiguruj lokalne środowisko gcloud SDK (jeśli jeszcze tego nie zrobiono), a potem zainstaluj komponent gcloud w wersji beta.

  2. Uruchom polecenie gcloud beta firebase test ios run i użyj tych flag, aby skonfigurować uruchomienie:

Flagi testów pętli gry
--type

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

--app

Wymagany: bezwzględna ścieżka (Google Cloud Storage lub system plików) do pliku IPA aplikacji. Ten parametr jest prawidłowy tylko podczas uruchamiania testów pętli gry.

--scenario-numbers

pętle (czyli scenariusze), które chcesz uruchomić w aplikacji. Możesz podać jedną pętlę, listę pętli lub zakres pętli. Domyślna pętla to 1.

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

--device-model

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

--timeout

Maksymalny czas trwania testu. Możesz wpisać liczbę całkowitą, aby reprezentować czas w sekundach, lub liczbę całkowitą i enumerację, aby reprezentować czas w dłuższej jednostce czasu.

Przykład:

  • --timeout=200 powoduje zakończenie testu po upływie maksymalnie 200 sekund.
  • --timeout=1h powoduje zakończenie testu po upływie godziny.

Na przykład poniższe polecenie uruchamia test pętli gry, który wykonuje pętle 1, 4, 6, 7 i 8 na iPhonie 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 o interfejsie wiersza poleceń gcloud znajdziesz w dokumentacji.

Uruchamianie testu lokalnie

Aby przeprowadzić test lokalnie, wczytaj aplikację do gier w symulatorze i uruchom:

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

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

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

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

Wcześniejsze kończenie testu

Domyślnie test pętli gry jest wykonywany do momentu upływu 5-minutowego limitu czasu, 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 Test Lab firebase-game-loop-complete w pliku AppDelegate aplikacji. Przykład:

Swift

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

Objective-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 uruchamia następną. Gdy nie ma już żadnych pętli do wykonania, test się kończy.

Pisanie niestandardowych wyników testów

Test Game Loop możesz skonfigurować tak, aby zapisywał niestandardowe wyniki testu w systemie plików urządzenia. Gdy test się rozpocznie, Test Lab przechowuje pliki wyników w katalogu GameLoopsResults na urządzeniu testowym (musisz go utworzyć samodzielnie). Po zakończeniu testu Test Lab przenosi wszystkie pliki z katalogu GameLoopResults do zasobnika projektu. Podczas konfigurowania testu pamiętaj o tych kwestiach:

  • Wszystkie pliki z wynikami są przesyłane niezależnie od typu, rozmiaru i liczby plików.

  • Test Lab nie przetwarza wyników testu, dopóki nie zakończą się wszystkie pętle w teście, więc jeśli test zawiera wiele pętli, które zapisują dane wyjściowe, dołącz je do osobnego pliku wyników lub utwórz plik wyników dla każdej pętli. Dzięki temu unikniesz zastępowania wyników z poprzedniej pętli.

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

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

  2. W dowolnym miejscu w kodzie aplikacji (np. w delegacie aplikacji) dodaj:

    Swift

    /// 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.
      }
    }
    

    Objective-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];
        }
    }