Catch up on everything we announced at this year's Firebase Summit. Learn more

Начните с тестов Game Loop для iOS

С помощью тестов Game Loop вы можете писать тесты, встроенные в ваш игровой движок, а затем запускать их в Test Lab на выбранных вами устройствах. Таким образом, вам не нужно беспокоиться о написании для другого пользовательского интерфейса или фреймворков тестирования. Тест Game Loop имитирует действия реального игрока, и когда вы запускаете его в Test Lab, он предоставляет быстрый и масштабируемый способ проверить, хорошо ли работает ваша игра для ваших пользователей.

На этой странице показано, как запустить тест Game Loop, а затем просмотреть результаты теста и управлять ими на странице Test Lab консоли Firebase. Вы также можете настроить свои тесты с дополнительными функциями, такими как записи результатов пользовательских тестов или окончания теста рано .

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

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

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

  • Запустите игру с настройками высочайшего качества, чтобы узнать, какие устройства могут ее поддерживать.

  • Выполните технический тест, например, скомпилируйте несколько шейдеров, выполните их и убедитесь, что результат соответствует ожиданиям.

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

Во-первых, вы должны зарегистрировать настраиваемую схему URL-адресов Firebase Test Lab в своем приложении:

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

  2. Перейдите на вкладку Info, затем добавить новый тип 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 (необязательно): настройте приложение для запуска нескольких циклов

Если в вашем приложении зарегистрировано несколько настраиваемых схем URL-адресов и вы планируете запускать несколько циклов (также называемых сценариями) в своем тесте, вы должны указать, какие циклы вы хотите запускать в своем приложении во время запуска.

В делегат своего приложения, переопределить 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
}

Цель-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).
}

Цель-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).
        }
    }
}

Шаг 3. Создайте и запустите тест

После регистрации пользовательской схемы URL тестовой лаборатории, вы можете запустить тест в Firebase консоли или с gcloud бета CLI . Если вы еще этого не сделали, сгенерируйте файл IPA для своего приложения (вам нужно будет найти его позже).

Запустите тест в консоли Firebase

  1. Если вы еще не сделали, откройте консоль Firebase и создать проект.

  2. На странице Test Lab в Firebase консоли выберите Run Ваш первый тест> Выполнить ИОС Game Loop.

  3. В разделе загрузки приложения, нажмите кнопку Обзор, затем выберите файл IPA вашего приложения (если вы уже не имеете, сгенерировать файл IPA для вашего приложения).

  4. Необязательно: Если вы хотите запустить несколько циклов (ака сценариев) в то время , или выбрать определенные циклы для запуска, введите число петель в области сценариев.

    Например, при вводе «1-3, 5», Тестовая лаборатория работает петля 1, 2, 3 и 5. По умолчанию (если вы не вводите ничего в поле Сценарии), Тестовая лаборатория работает только цикл 1.

  5. В разделе Устройства, выберите один или несколько физических устройств , которые вы хотите протестировать приложение на, затем нажмите кнопку Пуск тесты.

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

  1. Если вы еще не, настроить локальную среду gcloud SDK, то убедитесь , что установить gcloud бета - компонент .

  2. Запуск в gcloud beta firebase test ios run команду и использовать следующие флаги для настройки прогона:

Флаги для тестов Game Loop
--type

Требуется: Определяет тип теста IOS вы хотите запустить. Вы можете ввести типы тестовых xctest ( по умолчанию) или game-loop .

--app

Требуется: Абсолютный путь (Google Cloud Storage или файловая система) в файл IPA вашего приложения. Этот флаг действителен только при запуске тестов Game Loop.

--scenario-numbers

Циклы (также известные как сценарии), которые вы хотите запустить в своем приложении. Вы можете ввести один цикл, список или цикл или диапазон циклов. Цикл по умолчанию - 1.

Например, --scenario-numbers=1-3,5 проходит петлю 1, 2, 3 и 5.

--device-model

Физическое устройство , которое вы хотите запустить тест на (выяснить , какие доступны устройства можно использовать).

--timeout

Максимальная продолжительность выполнения теста. Вы можете ввести целое число, чтобы представить продолжительность в секундах, или целое число и перечисление, чтобы представить продолжительность как более длинную единицу времени.

Например:

  • --timeout=200 сил вашего теста прекратить , когда он работает до 200 секунд.
  • --timeout=1h заставляет тест прекратить , когда он работает до часа.

Например, следующая команда запускает тест Game Loop, который выполняет циклы 1, 4, 6, 7 и 8 на iPhone 8 Plus:

gcloud beta firebase test ios run
 --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8
 --device-model=iphone8plus

Для получения дополнительной информации о CLI gcloud см справочную документацию .

Провести тест локально

Чтобы запустить тест локально, загрузите игровое приложение в симулятор и запустите:

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

Завершить тест раньше

По умолчанию тест Game Loop продолжается до тех пор, пока не истечет тайм-аут в пять минут, даже если все циклы выполнены. Когда истечет время ожидания, тест завершится и все отложенные циклы будут отменены. Вы можете ускорить испытание или закончить его в начале, вызвав пользовательскую схему URL тестовой лаборатории в 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)
}

Цель-C

- (void)finishLoop {
  UIApplication *app = [UIApplication sharedApplication];
  [app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
      options:@{}
completionHandler:^(BOOL success) {}];
}

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

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

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

    Цель-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];
        }
    }