Запустите тест игрового цикла

Автоматизировать тестирование игр может быть сложно, если игровые приложения разработаны на основе разных UI-фреймворков. Тесты игрового цикла позволяют интегрировать собственные тесты с Test Lab и легко запускать их на выбранных устройствах. В этом руководстве описывается, как подготовить тест игрового цикла для запуска с помощью Firebase Test Lab .

О тестах игрового цикла

Что такое тест игрового цикла?

Тест игрового цикла имитирует действия реального игрока, чтобы быстро и масштабируемо проверить, насколько хорошо ваша игра работает для пользователей. Цикл — это полное или частичное выполнение теста в вашем игровом приложении. Вы можете запустить тест игрового цикла локально на симуляторе или на наборе устройств в Test Lab . Тесты игрового цикла можно использовать для:

  • Проходите игру так, как это делает конечный пользователь. Вы можете либо запрограммировать действия пользователя, либо позволить ему бездействовать, либо заменить его искусственным интеллектом (например, если вы реализовали искусственный интеллект в гоночной игре, то можете поручить водителю-ИИ управлять действиями пользователя).
  • Запустите игру с максимальными настройками качества, чтобы узнать, какие устройства ее поддерживают.
  • Запустите технический тест, например, скомпилируйте несколько шейдеров, выполните их и проверьте, соответствует ли результат ожидаемому.

Шаг 1 : Зарегистрируйте пользовательскую схему URL-адресов Test Lab

  1. В Xcode выберите целевой проект.

  2. Откройте вкладку «Информация» , затем добавьте новый тип URL .

  3. В поле «Схемы 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:) :

Быстрый

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

При запуске нескольких циклов в тесте текущий цикл передаётся в качестве параметра URL-адресу, используемому для запуска приложения. Вы также можете получить номер текущего цикла, проанализировав объект URLComponents , используемый для получения пользовательской схемы URL:

Быстрый

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 вашего приложения. Например:

Быстрый

/// 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) {}]; } 

Тест игрового цикла завершает текущий цикл и выполняет следующий. Когда циклов для выполнения больше нет, тест завершается.

Напишите пользовательские результаты теста

Вы можете настроить тест Game Loop для записи результатов в файловую систему вашего устройства. Таким образом, при запуске теста Test Lab сохранит файлы результатов в каталоге GameLoopsResults на вашем тестовом устройстве (который вам необходимо создать самостоятельно). По завершении теста Test Lab переместит все файлы из каталога GameLoopResults в контейнер вашего проекта. При настройке теста учитывайте следующее:

  • Все файлы результатов загружаются независимо от типа, размера или количества файлов.

  • Test Lab не обрабатывает результаты теста, пока все циклы в нём не завершатся. Поэтому, если ваш тест содержит несколько циклов, записывающих выходные данные, убедитесь, что вы добавляете их в отдельный файл результатов или создаете отдельный файл результатов для каждого цикла. Это позволит избежать перезаписи результатов предыдущего цикла.

Чтобы настроить тест для записи пользовательских результатов теста:

  1. В каталоге Documents вашего приложения создайте каталог с именем GameLoopResults .

  2. В любом месте кода вашего приложения (например, в делегате приложения) добавьте следующее:

    Быстрый

    /// 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 : Подпишите свое приложение

  1. Убедитесь, что все артефакты в приложении подписаны. Например, это можно сделать через Xcode, указав параметры подписи, такие как профиль подготовки и идентификатор. Подробнее см.: Apple Codesigning

Шаг 4 : Упакуйте приложение для загрузки

Создайте файл IPA для своего приложения (вам понадобится найти его позже).

  1. В раскрывающемся меню выберите «Продукт» > «Архив» . Выберите последний архив и нажмите «Распространить приложение» .

  2. В появившемся окне нажмите Разработка > Далее .

  3. Нажмите «Экспорт» , затем введите каталог, в который вы хотите загрузить IPA-файл вашего приложения.

Шаг 5 : Проверьте подпись приложения

  1. Проверьте подпись приложения, распаковав файл .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 .

  • Если запущен только один симулятор, введите специальную строку "booted" вместо SIMULATOR_UDID .

Если ваш тест содержит несколько циклов, вы можете указать, какой цикл вы хотите запустить, передав номер цикла флагу scenario . Обратите внимание, что при локальном запуске теста можно запустить только один цикл за раз. Например, если вы хотите запустить циклы 1, 2 и 5, необходимо выполнить отдельную команду для каждого цикла:

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

Следующие шаги

Запустите тест с помощью консоли Firebase или интерфейса командной строки gcloud .