Automatyzacja testowania gier może być trudna, gdy aplikacje do gier są tworzone na różnych platformach interfejsu. Testy pętli gry umożliwiają zintegrowanie testów natywnych z Test Lab i łatwe uruchamianie ich na wybranych urządzeniach. Z tego przewodnika dowiesz się, jak przygotować test pętli gry do uruchomienia w 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 sprawdzić, czy gra działa dobrze dla użytkowników w szybki i skalowalny sposób. Pętla to pełne lub częściowe wykonanie testu w grze mobilnej. Test pętli gry możesz uruchomić lokalnie na symulatorze lub na zestawie urządzeń w Test Lab. Testy pętli gry można wykorzystać do:
- przetestowania gry tak, jak zrobiłby to użytkownik końcowy; możesz zaprogramować dane wejściowe użytkownika , pozwolić mu na bezczynność lub zastąpić go sztuczną inteligencją (np. jeśli zaimplementujesz sztuczną inteligencję w grze wyścigowej, możesz powierzyć jej sterowanie);
- uruchomienia gry w najwyższej jakości, aby sprawdzić, które urządzenia ją obsługują;
- przeprowadzenia testu technicznego, np. skompilowania wielu shaderów, ich wykonania i sprawdzenia, czy dane wyjściowe są zgodne z oczekiwaniami.
Krok 1. Zarejestruj niestandardowy schemat URI adresu URL Test Lab
W Xcode wybierz cel projektu.
Kliknij kartę Informacje, a następnie dodaj nowy typ adresu URL.
W polu Schematy adresów URL wpisz
firebase-game-loop. Możesz też zarejestrować niestandardowy schemat URI adresu URL, dodając go do pliku konfiguracyjnego projektu w dowolnym miejscu w taguInfo.plist<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 uruchamiania testów w Test Lab.
Krok 2. Opcjonalnie skonfiguruj aplikację
Uruchamianie wielu pętli
Jeśli planujesz uruchomić w teście kilka pętli (czyli scenariuszy), musisz określić, które pętle chcesz uruchomić w aplikacji w momencie jej uruchomienia.
W delegacie aplikacji zastąp 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:).
}
}
Gdy uruchamiasz w teście kilka pętli, bieżąca pętla jest przekazywana jako parametr do adresu URL używanego do uruchamiania aplikacji. Możesz też uzyskać numer bieżącej pętli, analizując obiekt URLComponents używany do pobierania niestandardowego schematu URI adresu 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).
}
}
}
Wczesne zakończenie testu
Domyślnie test pętli gry jest wykonywany do momentu osiągnięcia limitu czasu wynoszącego 5 minut, nawet jeśli wszystkie pętle zostały już wykonane. Po osiągnięciu limitu czasu test się kończy i anuluje wszystkie oczekujące pętle. Możesz przyspieszyć test lub zakończyć go wcześniej, wywołując niestandardowy schemat URI adresu URL firebase-game-loop-complete w AppDelegate aplikacji.Test Lab 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 wykonuje następną. Gdy nie ma już pętli do uruchomienia, test się kończy.
Zapisywanie niestandardowych wyników testu
Możesz skonfigurować test pętli gry tak, aby zapisywał niestandardowe wyniki testu w systemie plików urządzenia. Dzięki temu, gdy test się rozpocznie, 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:
Wszystkie pliki wyników są przesyłane niezależnie od typu pliku, rozmiaru i liczby.
Test Lab nie przetwarza wyników testu, dopóki nie zostaną wykonane wszystkie pętle w teście. Jeśli więc test obejmuje kilka pętli, które zapisują dane wyjściowe, dopilnuj, aby były one dołączane do unikalnego pliku wyników lub aby dla każdej pętli był tworzony plik wyników. Dzięki temu unikniesz nadpisania wyników z poprzedniej pętli.
Aby skonfigurować test tak, aby zapisywał niestandardowe wyniki testu:
W katalogu
Documentsaplikacji utwórz katalog o nazwieGameLoopResults.W dowolnym miejscu w kodzie aplikacji (np. w delegacie aplikacji) dodaj te elementy:
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 artefakty w aplikacji są podpisane. Możesz to zrobić np. w Xcode, określając ustawienia podpisywania, takie jak profil aprowizacji i tożsamość. Więcej informacji znajdziesz w artykule Apple Codesigning.
Krok 4. Spakuj aplikację do przesłania
Wygeneruj plik IPA aplikacji (będziesz musiał go później znaleźć).
W wyświetlonym menu kliknij Product > Archive (Produkt > Archiwum). Wybierz najnowsze archiwum, a następnie kliknij Distribute App (Rozpowszechnij aplikację).
W wyświetlonym oknie kliknij Development > Next (Tworzenie > Dalej).
Kliknij Export (Eksportuj), a następnie wybierz katalog, w którym chcesz pobrać plik IPA aplikacji.
Krok 5. Sprawdź podpis aplikacji
- Sprawdź podpis aplikacji, rozpakowując plik .ipa, a następnie uruchamiając polecenie
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. Uruchom test lokalnie
Możesz uruchomić test lokalnie, aby sprawdzić jego działanie przed uruchomieniem go z Test Lab. Aby przetestować lokalnie, wczytaj grę mobilną w symulatorze i uruchom:
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
UDID symulatora znajdziesz, uruchamiając polecenie
instruments -s devices.Jeśli działa tylko 1 symulator, zamiast SIMULATOR_UDID wpisz specjalny ciąg znaków
"booted".
Jeśli test zawiera kilka pętli, możesz określić, którą pętlę chcesz uruchomić, przekazując jej numer do flagi scenario. Pamiętaj, że podczas uruchamiania testu lokalnie możesz uruchomić tylko jedną pętlę naraz. Jeśli np. 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=1xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5
Dalsze kroki
Uruchom test za pomocą konsoli Firebase lub gcloud CLI.