Автоматизировать тестирование игр бывает сложно, поскольку игровые приложения создаются на разных платформах. Тесты игрового цикла позволяют интегрировать собственные тесты с Test Lab и легко запускать их на выбранных устройствах. В этом руководстве рассказывается, как подготовить тест игрового цикла для запуска с помощью Firebase Test Lab.
Тесты с игровым циклом
Что такое тест с игровым циклом?
Тестирование игрового цикла имитирует действия реального игрока, чтобы быстро и масштабируемо проверить, насколько хорошо работает игра. Цикл – это полное или частичное прохождение теста в вашей мобильной игре. Вы можете запустить тест игрового цикла локально на симуляторе или на наборе устройств в Test Lab. Тесты с игровым циклом позволяют:
- Пройдите игру так, как это сделал бы обычный пользователь. Вы можете запрограммировать ввод данных пользователем, позволить пользователю бездействовать или заменить пользователя ИИ (например, если вы реализовали ИИ в игре с гонками на автомобилях, вы можете поручить ИИ-водителю ввод данных пользователя).
- Запустите игру с максимальными настройками качества, чтобы узнать, какие устройства ее поддерживают.
- Проведите технический тест, например скомпилируйте несколько шейдеров, выполните их и проверьте, соответствует ли результат ожидаемому.
Шаг 1. Зарегистрируйте собственную схему URL приложения Test Lab
В Xcode выберите целевой проект.
Нажмите на вкладку Информация и добавьте новый тип URL.
В поле URL Schemes (Схемы URL) введите
firebase-game-loop. Вы также можете зарегистрировать специальную схему URL, добавив ее в файл конфигурацииInfo.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>
Теперь в приложении можно проводить тестирование с помощью Test Lab.
Шаг 2. Настройте приложение (необязательно)
Как запустить несколько циклов
Если вы планируете запустить в тесте несколько циклов (сценариев), вам нужно указать, какие из них должны выполняться в приложении при запуске.
В делегате приложения переопределите метод 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:).
}
}
Когда вы запускаете несколько циклов тестирования, текущий цикл передается в качестве параметра в URL, используемый для запуска приложения. Вы также можете получить номер текущего цикла, проанализировав объект URLComponents, используемый для получения специальной схемы 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).
}
}
}
Как завершить тестирование раньше
По умолчанию тест игрового цикла выполняется до истечения пятиминутного тайм-аута, даже если все циклы уже завершены. Когда время ожидания истекает, тест завершается и отменяются все ожидающие циклы. Вы можете ускорить тестирование или завершить его раньше, вызвав специальную схему URL Test Lab firebase-game-loop-complete в AppDelegate приложения. Пример:
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 Lab сохранит файлы результатов в каталоге GameLoopsResults на вашем тестовом устройстве (который вы должны создать самостоятельно). По завершении теста Test Lab перемещает все файлы из каталога GameLoopResults в сегмент проекта. При настройке тестирования учитывайте следующее:
Все файлы результатов загружаются независимо от типа, размера и количества.
Test Lab не обрабатывает результаты тестирования, пока не будут выполнены все циклы, поэтому, если тест включает несколько циклов, которые записывают выходные данные, убедитесь, что вы добавляете их в уникальный файл результатов или создаете файл результатов для каждого цикла. Это позволит избежать перезаписи результатов предыдущего цикла.
Чтобы настроить тест для записи специальных результатов, выполните следующие действия:
В каталоге
Documentsприложения создайте каталог с названиемGameLoopResults.Добавьте в код приложения (например, в делегат приложения) следующий код:
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]; } }
Шаг 3. Подпишите приложение
Убедитесь, что все артефакты в приложении подписаны. Например, это можно сделать в Xcode, указав настройки подписи, такие как профиль инициализации и идентификатор. Дополнительную информацию можно найти на странице Подписывание кода Apple.
Шаг 4. Упакуйте приложение для загрузки
Создайте IPA-файл приложения (он понадобится вам позже).
В появившемся раскрывающемся меню нажмите Товар > Отправить в архив. Выберите последний архив и нажмите Распространить приложение.
В открывшемся окне нажмите Разработка > Далее.
Нажмите Экспортировать и укажите каталог, в который хотите скачать IPA-файл приложения.
Шаг 5. Проверьте подпись приложения
- Чтобы проверить подпись приложения, распакуйте файл IPA и выполните команду
codesign --verify --deep --verbose /path/to/MyApp.app, где MyApp – название приложения в распакованной папке (для каждого проекта оно будет разным). Ожидаемый результат:MyApp.app: valid on disk.
Шаг 6. Проверьте сайт локально
Вы можете запустить тест локально, чтобы проверить его поведение, прежде чем запускать его с помощью Test Lab. Чтобы протестировать мобильную игру локально, загрузите ее в симулятор и выполните следующие действия:
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
Чтобы узнать UDID симулятора, выполните команду
instruments -s devices.Если запущен только один симулятор, вместо SIMULATOR_UDID введите специальную строку
"booted".
Если в тесте несколько циклов, вы можете указать, какой из них нужно запустить, передав номер цикла флагу scenario. Обратите внимание, что при локальном тестировании можно запустить только один цикл. Например, если вы хотите выполнить циклы 1, 2 и 5, вам нужно выполнить отдельную команду для каждого цикла:
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
Дальнейшие действия
Запустите тестирование с помощью консоли Firebase или интерфейса командной строки gcloud.