Может быть сложно автоматизировать тестирование игр, когда игровые приложения созданы на разных фреймворках пользовательского интерфейса. Тесты Game Loop позволяют интегрировать собственные тесты с Test Lab и легко запускать их на выбранных вами устройствах. Тест Game Loop запускает ваш тест через ваше игровое приложение, имитируя действия реального игрока. В этом руководстве показано, как запустить тест Game Loop, а затем просмотреть и управлять результатами теста в консоли Firebase .
В зависимости от вашего игрового движка вы можете реализовать тесты с одним или несколькими циклами. Цикл — это полный или частичный прогон вашего теста в вашем игровом приложении. Игровые циклы можно использовать для:
- Запустите уровень вашей игры так же, как в него играл бы конечный пользователь. Вы можете либо заскриптовать ввод пользователя, позволить пользователю бездействовать или заменить пользователя ИИ, если это имеет смысл в вашей игре (например, у вас есть приложение для гонок и уже реализован ИИ. Вы можете легко назначить водителя ИИ ответственным за ввод пользователя).
- Запустите игру с максимальными настройками качества, чтобы проверить, поддерживают ли ее устройства.
- Проведите технический тест (скомпилируйте несколько шейдеров, выполните их, проверьте, соответствует ли вывод ожидаемому и т. д.).
Вы можете запустить тест Game Loop на одном тестовом устройстве, наборе тестовых устройств или в Test Lab . Однако мы не рекомендуем запускать тесты Game Loop на виртуальных устройствах, поскольку они имеют более низкую частоту кадров графики, чем физические устройства.
Прежде чем начать
Чтобы реализовать тест, необходимо сначала настроить приложение для тестов игрового цикла.
В манифесте приложения добавьте новый фильтр намерений к вашей активности :
<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 будет завершен. Тест полагается на фреймворк пользовательского интерфейса вашего приложения, чтобы начать следующий цикл, и закрытие вашего приложения сообщает ему, что тест завершен.
Создайте и запустите тест Game Loop
После настройки приложения для тестов Game Loop вы можете немедленно создать тест и запустить его в своем игровом приложении. Вы можете запустить тест в Test Lab , используя либо консоль Firebase , либо интерфейс командной строки gcloud (CLI) , либо на локальном устройстве, используя Test Loop Manager .
Запустить на локальном устройстве
Test Loop Manager от Test Lab — это приложение с открытым исходным кодом, которое помогает вам интегрировать тесты Game Loop и запускать их на локальных устройствах. Оно также позволяет вашей команде по обеспечению качества запускать те же игровые циклы на своих устройствах.
Чтобы запустить тест на локальном устройстве с помощью Test Loop Manager:
- Загрузите Test Loop Manager на телефон или планшет и установите его, выполнив:
adb install testloopmanager.apk
- На вашем устройстве откройте приложение Test Loop Apps на телефоне или планшете. Приложение отобразит список приложений на вашем устройстве, которые можно запустить с игровыми циклами. Если вы не видите здесь свое игровое приложение, убедитесь, что ваш фильтр намерений соответствует описанному в первом шаге раздела Перед началом работы .
- Выберите игровое приложение, затем выберите количество циклов, которые вы хотите запустить. Примечание: на этом этапе вы можете выбрать запуск подмножества циклов вместо одного цикла. Для получения дополнительной информации о запуске нескольких циклов одновременно см. Дополнительные функции .
- Нажмите Запустить тест . Ваш тест начнет выполняться немедленно.
Запуск в Test Lab
Вы можете запустить тест Game Loop в Test Lab используя либо консоль Firebase , либо gcloud CLI. Перед началом, если вы еще этого не сделали, откройте консоль Firebase и создайте проект.
Используйте консоль Firebase
- В консоли Firebase нажмите Test Lab на левой панели.
- Нажмите «Запустить свой первый тест» (или «Запустить тест», если в вашем проекте ранее уже проводился тест).
- Выберите «Игровой цикл» в качестве типа теста, затем нажмите «Продолжить» .
- Нажмите Browse , а затем перейдите к файлу
.apk
вашего приложения. Примечание: на этом этапе вы можете выбрать запуск подмножества циклов вместо одного цикла. Для получения дополнительной информации о запуске нескольких циклов одновременно см. Дополнительные функции . - Нажмите «Продолжить» .
- Выберите физические устройства, которые вы будете использовать для тестирования своего приложения.
- Нажмите «Начать тесты» .
Дополнительную информацию о начале работы с консолью Firebase см. в разделе Начало тестирования с помощью консоли Firebase .
Используйте командную строку gcloud (CLI)
Если вы еще этого не сделали, загрузите и установите 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 предлагает несколько дополнительных функций, которые позволяют дополнительно настраивать тесты, включая возможность записи выходных данных, поддержку нескольких игровых циклов и метки для связанных циклов.
Запись выходных данных
Ваш тест Game Loop может записывать выходные данные в файл, указанный в методе launchIntent.getData()
. После запуска теста вы можете получить доступ к этим выходным данным в разделе Test Lab консоли Firebase (см. Пример выходного файла теста Game Loop ).
Test Lab следует лучшим практикам для обмена файлами между приложениями, описанным в разделе Обмен файлами . В методе onCreate()
вашей активности, где находится ваше намерение, вы можете проверить свой выходной файл данных, выполнив следующий код:
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);
С++
#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, вы можете напрямую запустить этот игровой цикл, чтобы воспроизвести сбой и протестировать исправления ошибок.
Чтобы ваше приложение могло запускать несколько циклов одновременно:
Если вы проводите тест с помощью Test Loop Manager:
Добавьте следующую строку в манифест вашего приложения внутри элемента
<application>
:<meta-data android:name="com.google.test.loops" android:value="5" />
Это намерение запуска содержит целевой цикл как целочисленный параметр. В поле
android:value
можно указать целое число от 1 до 1024 (максимальное количество циклов, разрешенное для одного теста). Обратите внимание, что циклы индексируются, начиная с 1, а не с 0.В приложении Test Loop Manager появляется экран выбора, позволяющий выбрать цикл(ы), который вы хотите запустить. Если вы выбираете несколько циклов, каждый цикл запускается последовательно после завершения предыдущего цикла.
Если вы запускаете тест с помощью консоли Firebase , введите список или диапазон номеров циклов в поле «Сценарии» .
Если вы запускаете тест с помощью gcloud CLI, укажите список номеров циклов с помощью флага
--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
.
Метка игровых циклов
Когда вы помечаете свои игровые циклы одной или несколькими метками сценария, вы и ваша команда QA можете легко запустить набор связанных игровых циклов (например, «все игровые циклы совместимости») и протестировать их в одной матрице. Вы можете создать свои собственные метки или использовать предопределенные метки, предлагаемые Test Lab :
-
com.google.test.loops.player_experience
: Циклы, используемые для воспроизведения реального опыта пользователя во время игры. Целью тестирования с помощью этих циклов является поиск проблем, с которыми может столкнуться реальный пользователь во время игры. -
com.google.test.loops.gpu_compatibility
: Циклы для тестирования проблем, связанных с GPU. Целью тестирования с этими циклами является выполнение кода GPU, который может работать неправильно в рабочей среде, для выявления проблем с оборудованием и драйверами. -
com.google.test.loops.compatibility
: циклы, используемые для тестирования широкого спектра проблем совместимости, включая проблемы ввода-вывода и проблемы OpenSSL. -
com.google.test.loops.performance
: Циклы для тестирования производительности устройства. Например, игра может работать на самых сложных графических настройках, чтобы увидеть, как ведет себя новое устройство.
Чтобы ваше приложение могло запускать циклы с одинаковой меткой:
Если вы проводите тест с помощью Test Loop Manager:
В манифесте вашего приложения добавьте следующую строку метаданных и замените 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.В приложении Test Loop Manager введите одну или несколько меток в поле «Метки» .
Если вы запускаете тест с помощью консоли Firebase , введите одну или несколько меток в поле «Метки» .
Если вы запускаете тест с помощью интерфейса командной строки gcloud, укажите одну или несколько меток сценария с помощью флага
--scenario-labels
(например,--scenario-labels=performance,gpu
).
Поддержка лицензирования приложений
Test Lab поддерживает приложения, использующие службу лицензирования приложений, предлагаемую Google Play. Для успешной проверки лицензирования при тестировании вашего приложения с помощью Test Lab необходимо опубликовать приложение в производственном канале в магазине Play. Чтобы протестировать приложение в альфа- или бета-канале с помощью Test Lab , удалите проверку лицензирования перед загрузкой приложения в Test Lab .
Известные проблемы
Тесты игрового цикла в Test Lab имеют следующие известные проблемы:
- Некоторые сбои не поддерживают обратные трассировки. Например, некоторые сборки релиза могут подавлять вывод процесса
debuggerd
с помощьюprctl(PR_SET_DUMPABLE, 0)
. Чтобы узнать больше, см.debuggerd
. - Уровень API 19 в настоящее время не поддерживается из-за ошибок прав доступа к файлам.