Gradle 관리 기기로 테스트 확장

Gradle 관리 기기는 자동 계측 테스트의 일관성, 성능, 안정성을 개선합니다. API 수준 27 및 이후 버전에서 지원되는 이 기능을 사용하면 프로젝트의 Gradle 파일에서 가상 또는 원격 물리 테스트 기기를 구성할 수 있습니다. 빌드 시스템은 자동 테스트를 실행할 때 구성을 사용하여 이러한 기기를 완전히 관리(생성, 배포, 해체)합니다.

이 기능을 사용하면 Gradle이 실행 중인 테스트뿐 아니라 기기의 수명 주기까지 파악할 수 있으므로 테스트 환경의 품질이 다음과 같이 개선됩니다.

  • 기기 관련 문제를 처리하여 테스트의 실행을 보장합니다.
  • 가상 기기의 경우 에뮬레이터 스냅샷을 사용하여 기기 시작 시간과 메모리 사용량을 개선하고 테스트와 테스트 사이에 기기를 정리된 상태로 복원합니다.
  • 테스트 결과를 캐시하고 다른 결과를 제공할 가능성이 있는 테스트만 다시 실행합니다.
  • 로컬 테스트 실행과 원격 테스트 실행 간의 일관된 테스트 실행 환경을 제공합니다.

가상 Gradle 관리 기기 만들기

Gradle이 앱을 테스트하는 데 사용하도록 할 가상 기기를 모듈 수준 빌드 파일에서 지정할 수 있습니다. 다음 코드 샘플은 API 수준 30을 실행하는 Pixel 2를 Gradle 관리 기기로 만듭니다.

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

Groovy

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

기기 그룹 정의

여러 API 수준 및 폼 팩터와 같은 여러 기기 구성으로 테스트를 확장하려면 여러 개의 Gradle 관리 기기를 정의하여 명명된 그룹에 추가하면 됩니다. 그러면 Gradle이 그룹에 속한 모든 기기에서 동시에 테스트를 실행할 수 있습니다.

아래 예에서는 phoneAndTablet이라는 기기 그룹에 추가된 2개의 기기를 보여줍니다.

Kotlin

testOptions {
  managedDevices {
    localDevices {
      create("pixel2api29") { ... }
      create("nexus9api30") { ... }
    }
    groups {
      create("phoneAndTablet") {
        targetDevices.add(devices["pixel2api29"])
        targetDevices.add(devices["nexus9api30"])
      }
    }
  }
}

Groovy

testOptions {
  managedDevices {
    localDevices {
      pixel2api29 { ... }
      nexus9api30 { ... }
    }
    groups {
      phoneAndTablet {
        targetDevices.add(devices.pixel2api29)
        targetDevices.add(devices.nexus9api30)
      }
    }
  }
}

테스트 실행

구성한 Gradle 관리 기기를 사용하여 테스트를 실행하려면 다음 명령어를 사용합니다. device-name은 Gradle 빌드 스크립트(예: pixel2api30)에 구성한 기기의 이름이고 BuildVariant는 테스트하려는 앱의 빌드 변형입니다.

Windows:

gradlew device-nameBuildVariantAndroidTest

Linux 또는 macOS:

./gradlew device-nameBuildVariantAndroidTest

Gradle 관리 기기 그룹에서 테스트를 실행하려면 다음 명령어를 사용합니다.

Windows:

gradlew group-nameGroupBuildVariantAndroidTest

Linux 또는 macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

테스트 출력에는 테스트 보고서가 있는 HTML 파일의 경로가 포함됩니다. IDE에서 실행 > 테스트 기록을 클릭하면 테스트 결과를 Android 스튜디오로 가져와서 추가로 분석할 수도 있습니다.

테스트 샤딩 사용 설정

Gradle 관리 기기는 테스트 샤딩을 지원합니다. 테스트 샤딩을 사용하면 테스트 모음을 샤드라고 하는 동시에 실행되는 여러 개의 동일한 가상 기기 인스턴스에 분할할 수 있습니다. 테스트 샤딩을 사용하면 추가 컴퓨팅 리소스를 사용하는 대신 총 테스트 실행 시간을 줄일 수 있습니다.

주어진 테스트 실행에서 사용할 샤드의 개수를 설정하려면 gradle.properties 파일에서 다음을 설정합니다.

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

이 옵션을 사용하여 테스트를 실행하면 Gradle 관리 기기가 테스트 실행의 각 기기 프로필에 지정된 개수의 샤드를 프로비저닝합니다. 예를 들어 테스트를 3개의 기기로 이루어진 그룹에 배포하고 numManagedDeviceShards를 2로 설정하면 Gradle 관리 기기가 테스트 실행을 위해 총 6개의 가상 기기를 프로비저닝합니다.

테스트가 완료되면 Gradle이 테스트 실행에 사용된 각 샤드별로 .proto 파일에 테스트 결과를 출력합니다.

자동 테스트 기기 사용하기

Gradle 관리 기기는 계측 테스트를 실행할 때 CPU 및 메모리 리소스를 줄이도록 최적화된 자동 테스트 기기(ATD)라는 유형의 에뮬레이터 기기를 지원합니다. ATD는 다음과 같은 몇 가지 방법으로 런타임 성능을 개선합니다.

  • 일반적으로 앱 테스트에 유용하지 않은 사전 설치된 앱 삭제
  • 일반적으로 앱 테스트에 유용하지 않은 특정 백그라운드 서비스 사용 중지
  • 하드웨어 렌더링 사용 중지

시작하기 전에 Android Emulator를 사용 가능한 최신 버전으로 업데이트해야 합니다. 그런 다음 아래와 같이 모듈 수준의 빌드 파일에서 Gradle 관리 기기를 정의할 때 '-atd' 이미지를 지정합니다.

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

Groovy

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

다른 Gradle 관리 기기와 마찬가지로 기기 그룹을 만들 수도 있습니다. 성능 개선을 더욱 활용하려면 테스트 샤딩과 함께 ATD를 사용하여 테스트 모음의 총 테스트 실행 시간을 줄이면 됩니다.

ATD 이미지에서 삭제된 항목

ATD는 헤드리스 모드에서 작동하는 것 외에도 일반적으로 앱 코드 테스트에 필요하지 않은 앱과 서비스를 삭제하거나 사용 중지하여 성능을 최적화합니다. 아래 표에는 ATD 이미지에서 삭제 또는 사용 중지된 구성요소와 이러한 구성요소가 유용하지 않은 이유에 관한 설명이 나와 있습니다.

ATD 이미지에서 삭제된 항목 자동 테스트 실행 시 이 항목이 필요하지 않은 이유
Google 제품 앱:
  • 메일
  • 지도
  • Chrome
  • 메시지
  • Play 스토어 및 기타
자동 테스트는 다른 앱 또는 플랫폼은 올바르게 작동한다고 가정하고 자체 앱의 로직에 집중해야 합니다.

Espresso-Intents를 사용하면 발신 인텐트를 일치시키고 유효성을 검사하거나 실제 인텐트 응답 대신 스텁 응답을 제공할 수도 있습니다.

설정 앱 및 서비스:
  • CarrierConfig
  • EmergencyInfo
  • OneTimeInitializer
  • PhotoTable(화면 보호기)
  • 프로비저닝
  • 설정 앱
  • StorageManager
  • 전화 통신 APN 구성
  • WallpaperCropper
  • WallpaperPicker
이러한 앱은 최종 사용자가 플랫폼 설정을 변경하거나 기기를 설정하거나 기기 저장용량을 관리할 수 있는 GUI를 제공합니다. 이러한 앱은 일반적으로 앱 수준 자동 테스트의 범위를 벗어납니다.


참고: 설정 제공자는 ATD 이미지에서 계속 사용할 수 있습니다.

SystemUI 자동 테스트는 다른 앱 또는 플랫폼은 올바르게 작동한다고 가정하고 자체 앱의 로직에 집중해야 합니다.
AOSP 앱 및 서비스:
  • Browser2
  • 캘린더
  • Camera2
  • 연락처
  • 다이얼러
  • DeskClock
  • Gallery2
  • LatinIME
  • Launcher3QuickStep
  • 음악
  • QuickSearchBox
  • SettingsIntelligence
이러한 앱과 서비스는 일반적으로 앱 코드의 자동 테스트의 범위를 벗어납니다.

Firebase Test Lab 기기 사용하기

Gradle 관리 기기를 사용하는 경우 Firebase Test Lab 기기에서 자동화된 계측 테스트를 대규모로 실행할 수 있습니다. Test Lab을 사용하면 다양한 Android 기기(실제 기기와 가상 기기 모두 포함)에서 동시에 테스트를 실행할 수 있습니다. 이러한 테스트는 원격 Google 데이터 센터에서 실행됩니다. Gradle 관리 기기에서 지원되므로 빌드 시스템은 사용자의 구성에 따라 이러한 Test Lab 기기에 대해 실행 중인 테스트를 완전히 관리할 수 있습니다.

시작하기

다음 단계에서는 Gradle 관리 기기에서 Firebase Test Lab 기기를 사용하는 방법을 설명합니다. 이 단계에서는 gcloud CLI를 사용하여 사용자 인증 정보를 제공하며, 이 내용은 일부 개발 환경에는 적용되지 않을 수 있습니다. 필요에 따라 사용할 인증 프로세스를 자세히 알아보려면 애플리케이션 기본 사용자 인증 정보의 작동 방식을 참조하세요.

  1. Firebase 프로젝트를 만들려면 Firebase Console로 이동합니다. 프로젝트 추가를 클릭하고 화면의 프롬프트에 따라 프로젝트를 만듭니다. 프로젝트 ID를 기억합니다.

  2. Google Cloud CLI를 설치하려면 gcloud CLI 설치의 단계를 따르세요.

  3. 로컬 환경을 구성합니다.

    1. gcloud에서 Firebase 프로젝트에 연결합니다.

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. API 액세스를 위한 사용자 인증 정보 사용을 승인합니다. 모듈 수준의 빌드 스크립트에서 DSL을 사용하여 서비스 계정 JSON 파일을 Gradle에 전달하여 승인하는 것이 좋습니다.

      Kotlin

      firebaseTestLab {
        ...
        serviceAccountCredentials.set(file(SERVICE_ACCOUNT_JSON_FILE))
      }
      

      Groovy

      firebaseTestLab {
        ...
        serviceAccountCredentials = file(SERVICE_ACCOUNT_JSON_FILE)
      }
      

      또는 다음 터미널 명령어를 사용하여 수동으로 승인할 수도 있습니다.

      gcloud auth application-default login
      
    3. 선택사항: Firebase 프로젝트를 할당량 프로젝트로 추가합니다. 이 단계는 Test Lab 무료 할당량을 초과하는 경우에만 필요합니다.

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
      드림
  4. 필요한 API를 사용 설정합니다.

    Google Developers Console API 라이브러리 페이지에서 API 이름을 콘솔 상단의 검색창에 입력한 다음 각 API의 개요 페이지에 있는 API 사용 설정을 클릭하여 Cloud Testing APICloud Tool Results API를 사용 설정합니다.

  5. Android 프로젝트를 구성합니다.

    1. 최상위 빌드 스크립트에 Firebase Test Lab 플러그인을 추가합니다.

      Kotlin

      plugins {
        ...
        id("com.google.firebase.testlab") version "0.0.1-alpha05" apply false
      }
      

      Groovy

      plugins {
        ...
        id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false
      }
      
    2. gradle.properties 파일에서 맞춤 기기 유형을 사용 설정합니다.

      android.experimental.testOptions.managedDevices.customDevice=true
      
    3. 모듈 수준 빌드 스크립트에 Firebase Test Lab 플러그인을 추가합니다.

      Kotlin

      plugins {
       ...
       id "com.google.firebase.testlab"
      }
      

      Groovy

      plugins {
       ...
       id 'com.google.firebase.testlab'
      }
      

Test Lab 기기 지정하기

Gradle용 Firebase Test Lab 기기를 지정하여 모듈 수준 빌드 스크립트에서 앱을 테스트하는 데 사용할 수 있습니다. 다음 코드 샘플은 API 수준 30을 실행하는 Pixel 3를 ftlDevice라는 Gradle 관리 Test Lab 기기로 만듭니다. firebaseTestLab {} 블록은 com.google.firebase.testlab 플러그인을 모듈에 적용할 때 사용할 수 있습니다.

Kotlin

firebaseTestLab {
  managedDevices {
    create("ftlDevice") {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Groovy

firebaseTestLab {
  managedDevices {
    ftlDevice {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Firebase Test Lab 기기를 포함하여 Gradle 관리 기기의 그룹을 정의하려면 기기 그룹 정의를 참조하세요.

테스트를 실행하려면 다른 Gradle 관리 기기를 실행하는 데 사용되는 것과 동일한 명령어를 사용합니다. Gradle은 테스트를 동시에 실행하거나 Test Lab 기기의 다른 Google Cloud CLI 구성을 지원하지 않습니다.

스마트 샤딩으로 테스트 실행 최적화하기

Gradle 관리 Test Lab 기기의 테스트는 스마트 샤딩을 지원합니다. 스마트 샤딩은 각 샤드가 거의 동일한 시간 동안 실행되도록 샤드에 테스트를 자동으로 분산하므로 수동 할당 작업 및 전반적인 테스트 실행 시간이 줄어듭니다. 스마트 샤딩은 테스트 기록 또는 이전에 테스트를 실행하는 데 걸린 시간에 대한 정보를 사용하여 최적의 방식으로 테스트를 배포합니다. 스마트 샤딩을 사용하려면 Firebase Test Lab용 Gradle 플러그인 버전 0.0.1-alpha05가 필요합니다.

스마트 샤딩을 사용 설정하려면 각 샤드 내에서 테스트에 걸리는 시간을 지정합니다. 테스트가 완료되기 전에 샤드가 취소되지 않도록 하려면 타겟 샤드 기간을 timeoutMinutes보다 최소 5분 짧게 설정해야 합니다.

firebaseTestLab {
  ...
  testOptions {
    targetedShardDurationMinutes = 2
  }
}

자세한 내용은 Firebase Test Lab 기기 DSL 옵션을 참조하세요.

Test Lab 기기용 DSL 업데이트

테스트 실행을 맞춤설정하거나 이미 사용 중인 다른 솔루션에서 마이그레이션하는 데 도움이 되도록 구성할 수 있는 DSL 옵션이 더 많습니다. 다음 코드 스니펫에 설명되어 있는 이러한 옵션 중 일부를 참조하세요.

firebaseTestLab {
  ...

  /**
   * A path to a JSON file that contains service account credentials to access to
   * a Firebase Test Lab project.
   */
  serviceAccountCredentials.set(file("your_service_account_credentials.json"))


  testOptions {
    fixture {
      /**
       * Whether to grant permissions on the device before tests begin.
       * Available options are "all" or "none".
       *
       * Default value is "all".
       */
      grantedPermissions = "all"

      /**
       * Map of files to push to the device before starting the test.
       *
       * The key is the location on the device.
       * The value is the location of the file, either local or in Google Cloud.
       */
      extraDeviceFiles["/sdcard/dir1/file1.txt"] = "local/file.txt"
      extraDeviceFiles["/sdcard/dir2/file2.txt"] = "gs://bucket/file.jpg"

      /**
       * The name of the network traffic profile.
       *
       * Specifies network conditions to emulate when running tests.
       *
       * Default value is empty.
       */
      networkProfile = "LTE"
    }

    execution {
      /**
       * The maximum time to run the test execution before cancellation,
       * measured in minutes. Does not include the setup or teardown of device,
       * and is handled server-side.
       *
       * The maximum possible testing time is 45 minutes on physical devices
       * and 60 minutes on virtual devices.
       *
       * Defaults to 15 minutes.
       */
       timeoutMinutes = 30

      /**
       * Number of times the test should be rerun if tests fail.
       * The number of times a test execution should be retried if one
       * or more of its test cases fail.
       *
       * The max number of times is 10.
       *
       * The default number of times is 0.
       */
      maxTestReruns = 2

      /**
       * Ensures only a single attempt is made for each execution if
       * an infrastructure issue occurs. This doesn't affect `maxTestReruns`.
       * Normally, two or more attempts are made by Firebase Test Lab if a
       * potential infrastructure issue is detected. This is best enabled for
       * latency sensitive workloads. The number of execution failures might be
       * significantly greater with `failFast` enabled.
       *
       * Defaults to false.
       */
      failFast = false

      /**
       * The number of shards to split the tests across.
       *
       * Default to 0 for no sharding.
       */
      numUniformShards = 20
    }

    /**
     * For smart sharding, the target length of time each shard should takes in
     * minutes. Maxes out at 50 shards for physical devices and 100 shards for
     * virtual devices.
     *
     * Only one of numUniformShards or targetedShardDurationMinutes can be set.
     *
     * Defaults to 0 for no smart sharding.
     */
     targetedShardDurationMinutes = 15
    }

    results {
      /**
       * The name of the Google storage bucket to store the test results in.
       *
       * If left unspecified, the default bucket is used.
       *
       * Please refer to Firebase Test Lab permissions for required permissions
       * for using the bucket.
       */
      cloudStorageBucket = "bucketLocationName"

      /**
       * Name of test results for the Firebase console history list.
       * All tests results with the same history name are grouped
       * together in the Firebase console in a time-ordered test history list.
       *
       * Defaults to the application label in the APK manifest in Flank/Fladle.
       */
      resultsHistoryName = "application-history"

      /**
       * List of paths to copy from the test device's storage to the test
       * results folder. These must be absolute paths under /sdcard or
       * /data/local/tmp.
       */
      directoriesToPull.addAll(
        "/sdcard/path/to/something"
      )

      /**
       * Whether to enable video recording during the test.
       *
       * Disabled by default.
       */
      recordVideo = false

      /**
       * Whether to enable performance metrics. If enabled, monitors and records
       * performance metrics such as CPU, memory, and network usage.
       *
       * Defaults to false.
       */
      performanceMetrics = true
  }
}