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

Автоматизация тестирования игр может быть сложной задачей, особенно если игровые приложения созданы на основе различных фреймворков пользовательского интерфейса. Тесты Game Loop позволяют интегрировать ваши нативные тесты с Test Lab и легко запускать их на выбранных вами устройствах. В этом руководстве описано, как подготовить тест Game Loop для запуска с помощью 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.

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

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

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

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

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

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

  1. Проверьте подпись приложения, распаковав файл .ipa и запустив codesign --verify --deep --verbose /path/to/MyApp.app 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=1
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5

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

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