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. Z tego przewodnika dowiesz się, jak przygotować test pętli gry do uruchomienia za pomocą Firebase Test Lab.
Informacje o testach pętli gry
Co to jest test pętli gry?
Test pętli gry symuluje działania prawdziwego gracza, aby szybko i skalowalnie sprawdzić, czy Twoja gra działa prawidłowo dla użytkowników. Pętla to pełne lub częściowe przetestowanie aplikacji do gier. Możesz uruchomić test pętli gry lokalnie na symulatorze lub na zestawie urządzeń w Test Lab. Testy pętli gry umożliwiają:
- Przetestuj grę tak, jak robi to użytkownik. Możesz stworzyć skrypt z danymi wejściowymi użytkownika, pozwolić, aby użytkownik był nieaktywny, lub zastąpić go sztuczną inteligencją (na przykład jeśli wdrożyłeś sztuczną inteligencję w grze wyścigowej, możesz ustawić kierowcę AI jako odpowiedzialnego za dane wejściowe użytkownika).
- Uruchom grę z najwyższą jakością, aby sprawdzić, które urządzenia mogą ją obsługiwać.
- Przeprowadź test techniczny, na przykład skompiluj kilka shaderów, uruchom je i sprawdź, czy dane wyjściowe są zgodne z oczekiwaniami.
Krok 1. Zarejestruj niestandardowy schemat adresów URL Test Lab
W Xcode wybierz ustawienie projektu.
Kliknij kartę Informacje, a następnie dodaj nowy typ adresu URL.
W polu Schematy URL wpisz
firebase-game-loop
. Możesz też zarejestrować niestandardowy schemat adresu URL, dodając go do pliku konfiguracyjnegoInfo.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 przeprowadzania testów za pomocą Test Lab.
Krok 2. Opcjonalnie skonfiguruj aplikację
Uruchom wiele pętli
Jeśli planujesz uruchomić w ramach testu wiele pętli (czyli scenariuszy), musisz określić, które pętle chcesz uruchomić 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 <UIApplicationOpenURLOptionsKey, id> *)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).
}
}
}
Przerwanie 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.
Zapisywanie wyników testów niestandardowych
Test Game Loop możesz skonfigurować tak, aby zapisywał niestandardowe wyniki testu w systemie plików urządzenia. Dzięki temu po rozpoczęciu testu Test Lab przechowuje pliki wyników w katalogu GameLoopsResults
na 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 tych kwestiach:
Przesyłane są wszystkie pliki z wynikami wyszukiwania niezależnie od ich typu, rozmiaru i liczby.
Test Lab przetwarza wyniki testu dopiero wtedy, gdy wszystkie pętle w teście zostaną zakończone. Jeśli test obejmuje wiele pętli zapisujących dane wyjściowe, pamiętaj, by dołączyć je do unikalnego pliku wyników lub utworzyć plik wyników dla każdej pętli. W ten sposób unikniesz zastąpienia wyników z poprzedniej pętli.
Aby skonfigurować test w celu zapisywania niestandardowych wyników testu:
W katalogu
Documents
aplikacji utwórz katalog o nazwieGameLoopResults
.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]; } }
Krok 3. Podpisz aplikację
Upewnij się, że wszystkie elementy w aplikacji są podpisane. Możesz to zrobić na przykład w Xcode, określając ustawienia podpisywania, takie jak profil obsługi i tożsamość. Więcej informacji znajdziesz w artykule Apple Codesigning.
Krok 4. Spakuj aplikację na potrzeby przesłania
Wygeneruj plik IPA swojej aplikacji (będziesz go później potrzebować).
W wyświetlonym menu kliknij Produkt > Archiwizuj. Wybierz najnowsze archiwum, a następnie kliknij Rozpowszechniaj aplikację.
W wyświetlonym oknie kliknij Rozwój > Dalej.
Opcjonalnie: aby przyspieszyć kompilację, odznacz opcję Ponownie skompiluj z pliku binarnego, a potem kliknij Dalej. Test Lab nie wymaga skrócenia ani ponownej kompilacji aplikacji w celu przeprowadzenia testu, więc można bezpiecznie wyłączyć tę opcję.
Kliknij Eksportuj, a następnie wskaż katalog, do którego chcesz pobrać plik IPA aplikacji.
Krok 5. Sprawdź podpis aplikacji.
- Aby zweryfikować podpis aplikacji, rozpakuj plik .ipa, a potem uruchom
codesign --verify --deep --verbose /path/to/MyApp.app
, gdzie „MyApp” to nazwa aplikacji w rozpakowanym folderze (różni się w zależności od projektu). Oczekiwane dane wyjściowe toMyApp.app: valid on disk
.
Krok 6. Przeprowadź test lokalnie
Możesz uruchomić test lokalnie, aby sprawdzić jego działanie, zanim uruchomisz go z użyciem Test Lab. Aby przetestować grę lokalnie, wczytaj ją 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
Dalsze kroki
Uruchom test za pomocą konsoli Firebase lub interfejsu wiersza poleceń gcloud.