Автоматизация тестирования игр может быть сложной задачей, особенно если игровые приложения созданы на основе различных фреймворков пользовательского интерфейса. Тесты Game Loop позволяют интегрировать ваши нативные тесты с Test Lab и легко запускать их на выбранных вами устройствах. Тест Game Loop запускает ваше игровое приложение, имитируя действия реального игрока. В этом руководстве показано, как запустить тест Game Loop, а затем просмотреть и управлять результатами теста в консоли Firebase .
В зависимости от используемого игрового движка, вы можете реализовывать тесты с помощью одного или нескольких циклов. Цикл — это полное или частичное выполнение теста в вашем игровом приложении. Игровые циклы можно использовать для:
- Запустите уровень вашей игры так же, как это делал бы конечный пользователь. Вы можете либо запрограммировать ввод пользователя, либо оставить пользователя в режиме ожидания, либо заменить пользователя искусственным интеллектом, если это имеет смысл в вашей игре (например, предположим, у вас есть приложение для гонок на автомобилях, и у вас уже реализован ИИ. Вы можете легко назначить водителя-ИИ ответственным за ввод данных пользователем).
- Запустите игру с максимальными настройками качества, чтобы проверить, поддерживаются ли ваши устройства.
- Проведите техническое тестирование (скомпилируйте несколько шейдеров, запустите их, проверьте, соответствует ли результат ожидаемому и т. д.).
Тест игрового цикла можно запустить на одном тестовом устройстве, на нескольких тестовых устройствах или в Test Lab . Однако мы не рекомендуем запускать тесты игрового цикла на виртуальных устройствах, поскольку у них более низкая частота кадров, чем у физических устройств.
Прежде чем начать
Для реализации теста необходимо сначала настроить приложение для тестирования игрового цикла.
В файле манифеста приложения добавьте новый фильтр намерений к вашей активности :
<activity android:name=".MyActivity"> <intent-filter> <action android:name="com.google.intent.action.TEST_LOOP"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="application/javascript"/> </intent-filter> <intent-filter> ... (other intent filters here) </intent-filter> </activity>Это позволяет Test Lab запускать вашу игру, активируя её с помощью определённого намерения.
В свой код (рекомендуем добавить его в объявление метода
onCreate) добавьте следующее:Kotlin
val launchIntent = intent if (launchIntent.action == "com.google.intent.action.TEST_LOOP") { val scenario = launchIntent.getIntExtra("scenario", 0) // Code to handle your game loop here }
Java
Intent launchIntent = getIntent(); if(launchIntent.getAction().equals("com.google.intent.action.TEST_LOOP")) { int scenario = launchIntent.getIntExtra("scenario", 0); // Code to handle your game loop here }
Это позволяет вашей активности проверять намерение, которое её запускает. При желании вы также можете добавить этот код позже (например, после первоначальной загрузки игрового движка).
Рекомендуется: В конце теста добавить:
Kotlin
yourActivity.finish()
Java
yourActivity.finish();
Это закрывает ваше приложение после завершения теста игрового цикла. Тест использует фреймворк пользовательского интерфейса вашего приложения для запуска следующего цикла, и закрытие приложения сообщает ему о завершении теста.
Создайте и запустите тест игрового цикла.
После настройки приложения для тестов Game Loop вы можете сразу же создать тест и запустить его в своем игровом приложении. Вы можете запустить тест в Test Lab , используя консоль Firebase или интерфейс командной строки gcloud (CLI) , либо на локальном устройстве с помощью Test Loop Manager .
Запустить на локальном устройстве
Test Lab 's Test Loop Manager — это приложение с открытым исходным кодом, которое помогает интегрировать тесты игровых циклов и запускать их на локальных устройствах. Оно также позволяет вашей команде обеспечения качества запускать те же игровые циклы на своих устройствах.
Чтобы запустить тест на локальном устройстве с помощью менеджера тестовых циклов:
- Загрузите Test Loop Manager на свой телефон или планшет и установите его, выполнив команду:
adb install testloopmanager.apk
- Откройте приложение Test Loop Apps на своем телефоне или планшете. Приложение отобразит список приложений на вашем устройстве, которые можно запускать с помощью игровых циклов. Если вы не видите здесь свое игровое приложение, убедитесь, что ваш фильтр намерений соответствует описанному в первом шаге раздела «Перед началом работы» .
- Выберите игровое приложение, затем выберите количество циклов, которые вы хотите запустить. Примечание: на этом этапе вы можете выбрать запуск подмножества циклов вместо одного. Для получения дополнительной информации о запуске нескольких циклов одновременно см. раздел «Дополнительные функции» .
- Нажмите кнопку «Запустить тест» . Ваш тест начнет выполняться немедленно.
Запуск в Test Lab
В Test Lab можно запустить тест игрового цикла, используя либо консоль Firebase , либо CLI gcloud. Прежде чем начать, откройте консоль Firebase и создайте проект, если вы еще этого не сделали.
Используйте консоль Firebase
- В консоли Firebase нажмите Test Lab на левой панели.
- Нажмите «Запустить первый тест» (или «Запустить тест», если в вашем проекте уже проводились тесты).
- Выберите тип теста «Игровой цикл» , а затем нажмите «Продолжить» .
- Нажмите кнопку «Обзор» , а затем найдите файл
.apkвашего приложения. Примечание: на этом этапе вы можете выбрать запуск подмножества циклов вместо одного. Дополнительную информацию о запуске нескольких циклов одновременно см. в разделе «Дополнительные функции» . - Нажмите «Продолжить» .
- Выберите физические устройства, которые будут использоваться для тестирования вашего приложения.
- Нажмите « Начать тесты» .
Для получения дополнительной информации о начале работы с консолью Firebase см. раздел «Начало тестирования с помощью консоли Firebase .
Используйте командную строку (CLI) gcloud.
Если вы еще этого не сделали, скачайте и установите Google Cloud SDK.
Войдите в интерфейс командной строки gcloud, используя свою учетную запись Google:
gcloud auth loginУкажите свой проект Firebase в gcloud, где
PROJECT_ID— это идентификатор вашего проекта Firebase:gcloud config set project PROJECT_ID
Проведите свой первый тест:
gcloud firebase test android run \ --type=game-loop --app=<var>path-to-apk</var> \ --device model=herolte,version=23
Для получения дополнительной информации о начале работы с интерфейсом командной строки gcloud см. раздел «Начало тестирования из командной строки gcloud».
Дополнительные функции
Test Lab предлагает несколько дополнительных функций, позволяющих еще больше настраивать тесты, включая возможность записи выходных данных, поддержку нескольких игровых циклов и метки для связанных циклов.
Записать выходные данные
Ваш тест игрового цикла может записывать данные в файл, указанный в методе launchIntent.getData() . После запуска теста вы можете получить доступ к этим выходным данным в разделе Test Lab консоли Firebase (см. пример файла вывода теста игрового цикла ).
Test Lab следует лучшим практикам обмена файлами между приложениями, описанным в разделе «Обмен файлами» . В методе onCreate() вашего Activity, где находится ваш Intent, вы можете проверить файл с выходными данными, выполнив следующий код:
Kotlin
val launchIntent = intent val logFile = launchIntent.data logFile?.let { Log.i(TAG, "Log file ${it.encodedPath}") // ... }
Java
Intent launchIntent = getIntent(); Uri logFile = launchIntent.getData(); if (logFile != null) { Log.i(TAG, "Log file " + logFile.getEncodedPath()); // ... }
Если вы хотите записывать данные в файл из C++-части вашего игрового приложения, вы можете передать дескриптор файла вместо пути к файлу:
Kotlin
val launchIntent = intent val logFile = launchIntent.data var fd = -1 logFile?.let { Log.i(TAG, "Log file ${it.encodedPath}") fd = try { contentResolver .openAssetFileDescriptor(logFile, "w")!! .parcelFileDescriptor .fd } catch (e: FileNotFoundException) { e.printStackTrace() -1 } catch (e: NullPointerException) { e.printStackTrace() -1 } } // C++ code invoked here. // native_function(fd);
Java
Intent launchIntent = getIntent(); Uri logFile = launchIntent.getData(); int fd = -1; if (logFile != null) { Log.i(TAG, "Log file " + logFile.getEncodedPath()); try { fd = getContentResolver() .openAssetFileDescriptor(logFile, "w") .getParcelFileDescriptor() .getFd(); } catch (FileNotFoundException e) { e.printStackTrace(); fd = -1; } catch (NullPointerException e) { e.printStackTrace(); fd = -1; } } // C++ code invoked here. // native_function(fd);
C++
#include <unistd.h> JNIEXPORT void JNICALL Java_my_package_name_MyActivity_native_function(JNIEnv *env, jclass type, jint log_file_descriptor) { // The file descriptor needs to be duplicated. int my_file_descriptor = dup(log_file_descriptor); }
Пример выходного файла
Для отображения результатов тестирования игрового цикла в разделе Test Lab консоли Firebase можно использовать выходные файлы данных (отформатированные, как в примере ниже). Области, обозначенные как /.../ могут содержать любые необходимые пользовательские поля, если они не конфликтуют с именами других полей, используемых в этом файле:
{
"name": "test name",
"start_timestamp": 0, // Timestamp of the test start (in us).
Can be absolute or relative
"driver_info": "...",
"frame_stats": [
{
"timestamp": 1200000, // Timestamp at which this section was written
It contains value regarding the period
start_timestamp(0) -> this timestamp (1200000 us)
"avg_frame_time": 15320, // Average time to render a frame in ns
"nb_swap": 52, // Number of frame rendered
"threads": [
{
"name": "physics",
"Avg_time": 8030 // Average time spent in this thread per frame in us
},
{
"name": "AI",
"Avg_time": 2030 // Average time spent in this thread per frame in us
}
],
/.../ // Any custom field you want (vertices display on the screen, nb units …)
},
{
// Next frame data here, same format as above
}
],
"loading_stats": [
{
"name": "assets_level_1",
"total_time": 7850, // in us
/.../
},
{
"name": "victory_screen",
"total_time": 554, // in us
/.../
}
],
/.../, // You can add custom fields here
}
Несколько игровых циклов
В вашем приложении может оказаться полезным использовать несколько игровых циклов. Цикл — это полное прохождение игры от начала до конца. Например, если в вашей игре несколько уровней, вам может понадобиться один игровой цикл для запуска каждого уровня вместо одного цикла, который проходит по всем уровням. Таким образом, если ваше приложение вылетит на 32-м уровне, вы сможете напрямую запустить этот игровой цикл, чтобы воспроизвести сбой и протестировать исправления ошибок.
Чтобы ваше приложение могло запускать несколько циклов одновременно:
Если вы запускаете тест с помощью менеджера тестовых циклов:
Добавьте следующую строку в манифест вашего приложения внутри элемента
<application>:<meta-data android:name="com.google.test.loops" android:value="5" />
В этом интенте запуска целевой цикл указан в качестве целочисленного параметра. В поле
android:valueможно указать целое число от 1 до 1024 (максимальное количество циклов, разрешенное для одного теста). Обратите внимание, что индексация циклов начинается с 1, а не с 0.В приложении «Менеджер тестовых циклов» появляется экран выбора, позволяющий выбрать, какие циклы вы хотите запустить. Если вы выберете несколько циклов, каждый цикл будет запущен последовательно после завершения предыдущего.
Если вы запускаете тест с помощью консоли Firebase , введите список или диапазон номеров циклов в поле «Сценарии» .
Если вы запускаете тест с помощью CLI gcloud, укажите список номеров циклов, используя флаг
--scenario-numbers. Например,--scenario-numbers=1,3,5запускает циклы 1, 3 и 5.Если вы пишете код на C++ и хотите изменить поведение цикла, передайте в свой нативный код на C++ следующий дополнительный параметр:
Kotlin
val launchIntent = intent val scenario = launchIntent.getIntExtra("scenario", 0)
Java
Intent launchIntent = getIntent(); int scenario = launchIntent.getIntExtra("scenario", 0);
Теперь вы можете изменять поведение цикла в зависимости от полученного
intзначения.
Обозначьте игровые циклы
Если вы присвоите игровым циклам одну или несколько меток сценариев, вы и ваша команда контроля качества сможете легко запустить набор связанных игровых циклов (например, «игровые циклы со всей совместимостью») и протестировать их в единой матрице. Вы можете создавать собственные метки или использовать предопределенные метки, предлагаемые Test Lab :
-
com.google.test.loops.player_experience: Циклы for, используемые для воспроизведения реального пользовательского опыта во время игры. Цель тестирования с помощью этих циклов — выявить проблемы, с которыми столкнется реальный пользователь во время игры. -
com.google.test.loops.gpu_compatibility: Циклы for, используемые для тестирования проблем, связанных с графическим процессором. Цель тестирования с помощью этих циклов — запустить код для графического процессора, который может работать некорректно в производственной среде, чтобы выявить проблемы с оборудованием и драйверами. -
com.google.test.loops.compatibility: Циклы for, используемые для проверки широкого спектра проблем совместимости, включая проблемы ввода-вывода и проблемы OpenSSL. -
com.google.test.loops.performance: Циклы for, используемые для проверки производительности устройства. Например, игру можно запустить с максимальными настройками графики, чтобы посмотреть, как ведет себя новое устройство.
Чтобы ваше приложение могло запускать циклы с одинаковой меткой:
Если вы запускаете тест с помощью менеджера тестовых циклов:
В манифест вашего приложения добавьте следующую строку метаданных и замените LABEL_NAME на метку по вашему выбору:
<meta-data android:name="com.google.test.loops.LABEL_NAME" android:value="1,3-5" />
В поле
android:valueможно указать диапазон или набор целых чисел от 1 до 1024 (максимальное количество циклов, разрешенное для одного теста), которые представляют циклы, которые вы хотите пометить. Обратите внимание, что индексация циклов начинается с 1, а не с 0. Например,android:value="1,3-5"применяет LABEL_NAME к циклам 1, 3, 4 и 5.В приложении «Менеджер тестовых циклов» введите одну или несколько меток в поле «Метки» .
Если вы запускаете тест с помощью консоли Firebase , введите одну или несколько меток в поле «Метки» .
Если вы запускаете тест с помощью CLI gcloud, укажите одну или несколько меток сценария, используя флаг
--scenario-labels(например,--scenario-labels=performance,gpu).
Поддержка лицензирования приложений
Test Lab поддерживает приложения, использующие сервис лицензирования приложений, предоставляемый Google Play. Для успешной проверки лицензирования при тестировании вашего приложения с помощью Test Lab необходимо опубликовать приложение в производственном канале Play Store. Для тестирования приложения в альфа- или бета-канале с помощью Test Lab снимите проверку лицензирования перед загрузкой приложения в Test Lab .
Известные проблемы
В тестах игрового цикла в Test Lab обнаружены следующие известные проблемы:
- Для некоторых сбоев трассировка стека не поддерживается. Например, в некоторых релизных сборках вывод процесса
debuggerdможет быть подавлен с помощьюprctl(PR_SET_DUMPABLE, 0). Для получения дополнительной информации см.debuggerd. - В настоящее время API уровня 19 не поддерживается из-за ошибок прав доступа к файлам.