Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

게임 루프 테스트 시작하기

게임 앱이 서로 다른 UI 프레임워크에 구축되면 게임 테스트를 자동화하기 어려울 수 있습니다. 게임 루프 테스트를 사용하면 기본 테스트를 Test Lab과 통합하고 선택한 장치에서 쉽게 실행할 수 있습니다. 게임 루프 테스트는 실제 플레이어의 동작을 시뮬레이션하면서 게임 앱을 통해 테스트를 실행합니다. 이 가이드는 게임 루프 테스트를 실행한 다음 Firebase 콘솔에서 테스트 결과를 보고 관리하는 방법을 보여줍니다.

게임 엔진에 따라 단일 또는 다중 루프 로 테스트를 구현할 수 있습니다. 루프는 게임 앱에서 테스트를 전체적으로 또는 부분적으로 실행하는 것입니다. 게임 루프는 다음과 같은 용도로 사용할 수 있습니다.

  • 최종 사용자가 플레이하는 것과 같은 방식으로 게임 레벨을 실행합니다. 사용자의 입력을 스크립팅하거나, 사용자를 유휴 상태로 두거나, 게임에서 의미가 있는 경우 사용자를 AI로 대체할 수 있습니다(예: 경주용 자동차 게임 앱이 있고 이미 AI가 구현되어 있다고 가정). 사용자 입력을 담당하는 AI 드라이버를 쉽게 배치).
  • 장치가 지원하는지 확인하려면 최고 품질 설정에서 게임을 실행하십시오.
  • 기술 테스트 실행(여러 셰이더 컴파일, 실행, 출력이 예상대로인지 확인 등).

단일 테스트 기기, 테스트 기기 세트 또는 Test Lab에서 게임 루프 테스트를 실행할 수 있습니다. 그러나 실제 장치보다 그래픽 프레임 속도가 낮기 때문에 가상 장치에서 게임 루프 테스트를 실행하지 않는 것이 좋습니다.

시작하기 전에

테스트를 구현하려면 먼저 게임 루프 테스트를 위해 앱을 구성해야 합니다.

  1. 앱 매니페스트에서 활동 에 새 인텐트 필터를 추가합니다.

    <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에서 특정 의도로 게임을 트리거하여 게임을 시작할 수 있습니다.

  2. 코드에서( onCreate 메서드 선언 내부에 권장) 다음을 추가합니다.

    Kotlin+KTX

    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
    }

    이렇게 하면 활동이 활동을 시작하는 의도를 확인할 수 있습니다. 원하는 경우 나중에 이 코드를 추가할 수도 있습니다(예: 게임 엔진을 처음 로드한 후).

  3. 권장 사항: 테스트가 끝날 때 다음을 추가합니다.

    Kotlin+KTX

    yourActivity.finish()

    Java

    yourActivity.finish();

    그러면 게임 루프 테스트가 완료되면 앱이 닫힙니다. 테스트는 다음 루프를 시작하기 위해 앱의 UI 프레임워크에 의존하며 앱을 닫으면 테스트가 완료되었음을 알립니다.

게임 루프 테스트 생성 및 실행

게임 루프 테스트를 위해 앱을 구성한 후 즉시 테스트를 생성하고 게임 앱에서 실행할 수 있습니다. Firebase 콘솔 또는 gcloud 명령줄 인터페이스(CLI) 를 사용하여 Test Lab에서 테스트를 실행하거나 Test Loop Manager를 사용하여 로컬 기기 에서 테스트를 실행하도록 선택할 수 있습니다.

로컬 장치에서 실행

Test Lab의 Test Loop Manager 는 게임 루프 테스트를 통합하고 로컬 장치에서 실행하는 데 도움이 되는 오픈 소스 앱입니다. 또한 품질 보증 팀이 장치에서 동일한 게임 루프를 실행할 수 있습니다.

테스트 루프 관리자를 사용하여 로컬 장치에서 테스트를 실행하려면:

  1. 휴대폰이나 태블릿에 Test Loop Manager 를 다운로드하고
    adb install testloopmanager.apk
    을 실행하여 설치합니다.
  2. 기기에서 휴대폰 또는 태블릿의 Test Loop Apps 앱을 엽니다. 앱은 게임 루프로 실행할 수 있는 장치의 앱 목록을 표시합니다. 여기에 게임 앱이 표시되지 않으면 인텐트 필터가 시작하기 전에 섹션 의 첫 번째 단계에서 설명한 것과 일치하는지 확인하세요.
  3. 게임 앱을 선택한 다음 실행할 루프 수를 선택합니다. 참고: 이 단계에서 하나의 루프 대신 루프의 하위 집합을 실행하도록 선택할 수 있습니다. 한 번에 여러 루프를 실행하는 방법에 대한 자세한 내용은 선택적 기능을 참조하세요.
  4. 테스트 실행 을 클릭합니다. 테스트가 즉시 실행되기 시작합니다.

테스트 랩에서 실행

Firebase Console 또는 gcloud CLI를 사용하여 Test Lab에서 게임 루프 테스트를 실행할 수 있습니다. 시작하기 전에 아직 하지 않았다면 Firebase 콘솔 을 열고 프로젝트를 만드세요.

Firebase 콘솔 사용

  1. Firebase 콘솔의 왼쪽 패널에서 Test Lab 을 클릭합니다.
  2. 첫 번째 테스트 실행(또는 프로젝트에서 이전에 테스트를 실행 한 경우 테스트 실행)을 클릭합니다.
  3. 테스트 유형으로 게임 루프 를 선택한 다음 계속 을 클릭합니다.
  4. 찾아보기 를 클릭한 다음 앱의 .apk 파일을 찾습니다. 참고: 이 단계에서 하나의 루프 대신 루프의 하위 집합을 실행하도록 선택할 수 있습니다. 한 번에 여러 루프를 실행하는 방법에 대한 자세한 내용은 선택적 기능을 참조하세요.
  5. 계속 을 클릭합니다.
  6. 앱을 테스트하는 데 사용할 물리적 기기를 선택하세요.
  7. 테스트 시작 을 클릭합니다.

Firebase 콘솔 시작에 대한 자세한 내용은 Firebase 콘솔로 테스트 시작을 참조하세요.

gcloud 명령줄(CLI) 사용

  1. 아직 하지 않았다면 Google Cloud SDK를 다운로드하여 설치합니다.

  2. Google 계정을 사용하여 gcloud CLI에 로그인합니다.

    gcloud auth login

  3. gcloud에서 Firebase 프로젝트를 설정합니다. 여기서 PROJECT_ID 는 Firebase 프로젝트의 ID입니다.

    gcloud config set project PROJECT_ID
    
  4. 첫 번째 테스트 실행:

    gcloud firebase test android run \
     --type=game-loop --app=<var>path-to-apk</var> \
     --device model=herolte,version=23
    

gcloud CLI 시작에 대한 자세한 내용 은 gcloud 명령줄에서 테스트 시작을 참조하세요.

선택적 기능

Test Lab은 출력 데이터 작성 기능, 여러 게임 루프 지원, 관련 루프 레이블을 포함하여 테스트를 추가로 사용자 지정할 수 있는 몇 가지 선택적 기능을 제공합니다.

출력 데이터 쓰기

게임 루프 테스트는 launchIntent.getData() 메서드에 지정된 파일에 출력을 쓸 수 있습니다. 테스트를 실행한 후 Firebase 콘솔의 Test Lab 섹션에서 이 출력 데이터에 액세스할 수 있습니다( 게임 루프 테스트 출력 파일 예 참조).

Test Lab은 파일 공유에 설명된 앱 간 파일 공유에 대한 권장사항을 따릅니다. 의도가 있는 활동의 onCreate() 메서드에서 다음 코드를 실행하여 데이터 출력 파일을 확인할 수 있습니다.

Kotlin+KTX

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+KTX

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);
}

출력 파일 예

출력 데이터 파일(아래 예와 같은 형식)을 사용하여 Firebase 콘솔의 Test Lab 섹션에 게임 루프 테스트 결과를 표시할 수 있습니다. /.../ 로 표시된 영역은 이 파일에서 사용된 다른 필드의 이름과 충돌하지 않는 한 필요한 모든 사용자 정의 필드를 포함할 수 있습니다.

{
  "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로 테스트를 실행하는 경우:

    1. <application> 요소 내부의 앱 매니페스트에 다음 줄을 추가합니다.

      <meta-data
        android:name="com.google.test.loops"
        android:value="5" />
      

      이 시작 인텐트에는 대상 루프가 정수 매개변수로 포함되어 있습니다. android:value 필드에서 1에서 1024까지의 정수(단일 테스트에 허용되는 최대 루프 수)를 지정할 수 있습니다. 루프는 0이 아닌 1부터 인덱싱됩니다.

    2. Test Loop Manager 앱에서 실행할 루프를 선택할 수 있는 선택 화면이 나타납니다. 여러 루프를 선택하면 이전 루프가 완료된 후 각 루프가 순서대로 실행됩니다.

  • Firebase 콘솔로 테스트를 실행 중인 경우 시나리오 필드에 목록 또는 루프 번호 범위를 입력합니다.

  • gcloud CLI로 테스트를 실행하는 경우 --scenario-numbers 플래그를 사용하여 루프 번호 목록을 지정합니다. 예를 들어 --scenario-numbers=1,3,5 는 루프 1, 3, 5를 실행합니다.

  • C++를 작성 중이고 루프의 동작을 변경하려는 경우 네이티브 C++ 코드에 다음 추가 항목을 전달합니다.

    Kotlin+KTX

    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 : 게임 플레이 시 실제 사용자 경험을 재현하는 데 사용되는 For 루프입니다. 이러한 루프로 테스트하는 목표는 실제 사용자가 게임을 플레이하는 동안 직면할 수 있는 문제를 찾는 것입니다.
  • com.google.test.loops.gpu_compatibility : GPU 관련 문제를 테스트하는 데 사용되는 For 루프입니다. 이러한 루프를 사용한 테스트의 목표는 프로덕션에서 제대로 실행되지 않을 수 있는 GPU 코드를 실행하여 하드웨어 및 드라이버 문제를 노출하는 것입니다.
  • com.google.test.loops.compatibility : I/O 문제 및 OpenSSL 문제를 포함하여 광범위한 호환성 문제를 테스트하는 데 사용되는 For 루프입니다.
  • com.google.test.loops.performance : 기기의 성능을 테스트하는 데 사용되는 For 루프입니다. 예를 들어 게임은 가장 복잡한 그래픽 설정에서 실행되어 새 장치가 어떻게 작동하는지 확인할 수 있습니다.

앱이 동일한 레이블로 루프를 실행하도록 하려면 다음을 수행하십시오.

  • Test Loop Manager로 테스트를 실행하는 경우:

    1. 앱의 매니페스트에서 다음 메타데이터 줄을 추가하고 LABEL_NAME 을 선택한 라벨로 바꿉니다.

      <meta-data
       android:name="com.google.test.loops.LABEL_NAME"
       android:value="1,3-5" />
      

      android:value 필드에서 라벨을 지정하려는 루프를 나타내는 범위 또는 1~1024(단일 테스트에 허용되는 최대 루프 수)의 정수 집합을 지정할 수 있습니다. 루프는 0이 아닌 1부터 인덱싱됩니다. 예를 들어 android:value="1,3-5"LABEL_NAME 을 루프 1, 3, 4, 5에 적용합니다.

    2. Test Loop Manager 앱에서 레이블 필드에 하나 이상의 레이블을 입력하십시오.

  • Firebase 콘솔로 테스트를 실행 중인 경우 라벨 필드에 하나 이상의 라벨을 입력합니다.

  • gcloud CLI로 테스트를 실행하는 경우 --scenario-labels 플래그(예: --scenario-labels=performance,gpu )를 사용하여 하나 이상의 시나리오 라벨을 지정합니다.

앱 라이선스 지원

Test Lab은 Google Play에서 제공하는 앱 라이선스 서비스를 사용하는 앱을 지원합니다. Test Lab에서 앱을 테스트할 때 라이선스를 성공적으로 확인하려면 Play 스토어의 프로덕션 채널에 앱을 게시해야 합니다. Test Lab을 사용하여 알파 또는 베타 채널에서 앱을 테스트하려면 Test Lab에 앱을 업로드하기 전에 라이선스 확인을 제거하세요.

알려진 문제

Test Lab의 게임 루프 테스트에는 다음과 같은 알려진 문제가 있습니다.

  • 일부 충돌은 역추적을 지원하지 않습니다. 예를 들어 일부 릴리스 빌드는 prctl(PR_SET_DUMPABLE, 0) 을 사용하여 debuggerd 프로세스의 출력을 억제할 수 있습니다. 자세한 내용은 debuggerd 를 참조하십시오.
  • API 레벨 19는 파일 권한 오류로 인해 현재 지원되지 않습니다.