이동식 저장소

[Android] Gradle Managed Devices로 테스트하기 본문

Primary/Android

[Android] Gradle Managed Devices로 테스트하기

해스끼 2022. 12. 8. 15:12

``androidTest`` 폴더에 있는 instrumented test는 에뮬레이터를 통해 테스트될 수 있다. 그런데 에뮬레이터는 메모리도 많이 잡아먹고, UI까지 전부 그리기 때문에 unit test보다 더 무겁다는 느낌이 있다. 에뮬레이터를 매번 켜는 게 번거롭기도 하고, 그래서 그런지 개발하는 입장에서도 자주 실행하지 않게 된다. 테스트는 모름지기 자주 실행되어야 하는 법이거늘.

Gradle Managed Devices

매번 에뮬레이터를 켜는 대신 Gradle Managed Devices를 사용하면 instrumented test를 더 간편하게 실행할 수 있다고 한다. 대략 다음의 작업을 대신 해 준다.

  • 기기와 관련된 작업을 대신 처리 (기기를 켜고 끄는 등)
  • 기기를 켜는 시간을 단축하고 테스트 환경을 빠르게 세팅하기 위해 emulator snapshot을 활용. 이전 테스트의 결과가 다른 테스트에 영향을 미치지 않도록 상태를 초기화할 때 snapshot을 이용한다.
  • 테스트 결과를 캐시하여 변경되지 않은 테스트는 실행하지 않음
  • 로컬, 원격 등의 모든 환경에서 일관된 테스트 환경 제공

정리하면 에뮬레이터는 Gradle에서 처리해줄 테니 테스트만 잘 짜라는 것이다. 우리도 직접 사용해 보자.

Gradle Managed Devices 정의하기

Module level ``build.gradle``에서 기기를 정의할 수 있다. 당연히 ``androidTest``가 있는 모듈에 정의해야 한다.

android {
  testOptions {
    managedDevices {
      devices {
        maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api30").apply {
          device = "Pixel 2"
          apiLevel = 30
          systemImageSource = "aosp"
        }
      }
    }
  }
}

``systemImageSource``는 ``google``을 기본으로 사용하지만, 구글맵 등 Google API가 필요없는 테스트라면 더 가벼운 ``aosp``(Android Open Source Project) 이미지를 사용할 수 있다.

 

글 쓰는 시점 기준으로 API 27 이상인 기기만 사용할 수 있다. Experimental 기능을 활성화하면 API 26 이하도 사용할 수 있지만, 권장하지는 않는다고 한다.

A problem occurred configuring project ':preferences'.
> Could not create task ':preferences:pixel2api23DebugAndroidTest'.
   > API level 26 and lower is currently not supported for Gradle Managed devices.
     Your current configuration requires API level 23.
     While it's not recommended, you can use API levels 26 and lower by adding
     android.experimental.testOptions.managedDevices.allowOldApiLevelDevices=true
     to your gradle.properties file.

일단 테스트를 실행해 보자. 다음의 커맨드로 테스트를 실행할 수 있다.

gradlew [device-name][BuildVariant]AndroidTest

예를 들어 기기 이름이 ``pixel2api30``이고 build variant가 ``debug``라면 테스트 커맨드는 ``gradlew pixel2api30DebugAndroidTest``이다. 처음 실행하면 시스템 이미지를 다운로드하는 데 시간이 조금 걸릴 것이다. 이미지가 설치된 후에는 빠르게 실행할 수 있다.

(시스템 설치 중)

...

> Task :preferences:pixel2api30DebugAndroidTest
Starting 6 tests on pixel2api30

> Task :preferences:mergeDebugAndroidTestTestResultProtos
Test execution completed. See the report at: (리포트 경로)

BUILD SUCCESSFUL in 26s
55 actionable tasks: 33 executed, 22 up-to-date

Build Analyzer results available
오후 2:34:13: Execution finished 'preferences:pixel2api30DebugAndroidTest'.

테스트 보고서

에뮬레이터를 켠다던가 하는 심리적 장벽 없이 깔끔하게 실행되었다. 앞으로 ``androidTest``를 더 자주 실행할 수 있겠다.

여러 기기를 그룹으로 묶기

안드로이드는 특성상 하나의 API 버전에서만 테스트해서는 안 된다. 여러 API 버전에서 테스트를 실행해 봐야 하는데, Gradle에서는 여러 기기를 그룹으로 묶어 한 번에 테스트할 수 있는 기능을 제공한다.

 

문법은 다음과 같다.

testOptions {
  managedDevices {
    devices {
      maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api29").apply { ... }
      maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("nexus9api30").apply { ... }
    }
    groups {
      maybeCreate("phoneAndTablet").apply {
        targetDevices.add(devices["pixel2api29"])
        targetDevices.add(devices["nexus9api30"])
      }
    }
  }
}

테스트 실행 커맨드는 다음과 같다. 커맨드가 조금 길지만 제대로 타이핑해 보자.

gradlew [group-name]Group[BuildVariant]AndroidTest
(빌드 중)

...

> Task :preferences:pixel2api27DebugAndroidTest
additionalTestOutput is not supported on Gradle managed devices running API level < 29
Starting 6 tests on pixel2api27

> Task :preferences:pixel2api30DebugAndroidTest
Starting 6 tests on pixel2api30

> Task :preferences:mergeDebugAndroidTestTestResultProtos
Test execution completed. See the report at: (리포트 경로)

> Task :preferences:api27and30GroupDebugAndroidTest

BUILD SUCCESSFUL in 28s
57 actionable tasks: 35 executed, 22 up-to-date

Build Analyzer results available
오후 2:42:02: Execution finished 'preferences:api27and30GroupDebugAndroidTest'.

그룹이 제대로 적용되었다.

Automated Test Devices?

Gradle Managed Devices에는 Automated Test Devices(ATD)라는 새로운 기기가 추가되었다. ATD는 안드로이드의 기본 앱이나 백그라운드 서비스처럼 테스트에 필요없는 기능을 모두 제거하여 경량화된 기기이다. 심지어 하드웨어 렌더링 기능까지 제거했다고 한다. 이런 특성 탓에 하드웨어 렌더링에 의존하는 특정 UI 테스트는 실행할 수 없지만, 그 외의 테스트는 아주 빠르게 실행할 수 있다.

 

구체적으로 제거된 기능을 모두 보고 싶다면 이 링크를 참고하자.

 

ATD 기기를 사용하려면 기기를 정의할 때 ``systemImageSource``의 값 뒤에 ``atd``를 붙이면 된다. ``aosp-atd``와 ``google-atd`` 모두 가능하다. 현재 시점에서는 API 30 이미지만 사용할 수 있다.

android {
  testOptions {
    managedDevices {
      devices {
        maybeCreate<com.android.build.api.dsl.ManagedVirtualDevice>("pixel2api30").apply {
          device = "Pixel 2"
          apiLevel = 30
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

실제로 테스트해 보니 atd 기기가 미세하게 더 빠르다. 확실히 가볍긴 한가보다.


Test sharding 활성화하기

굳이 구분선을 그은 이유는 optional한 내용이기 때문이다.

 

Gradle Managed Devices로 테스트를 실행할 때, 테스트를 여러 기기에서 실행하여 테스트를 빠르게 수행할 수 있다. 정확히는 테스트를 동일한 사양의 기기 여러 대에서 나눠 실행하는 것이다. 이처럼 데이터를 여러 조각으로 나눠 처리하는 기술을 sharding이라고 한다.

 

``gradle.properties`` 파일에서 활성화할 수 있다.

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

CPU나 메모리가 넘칠 정도로 많은 경우에만 사용하자. 메모리가 부족해지면 Gradle에서 timeout error가 발생할 수도 있다.

더 보기

 

Gradle 관리 기기를 사용해 대규모 테스트 실행  |  Android 개발자  |  Android Developers

Gradle 관리 기기를 사용하여 자동 계측 테스트를 대규모로 실행하는 방법

developer.android.com

 

'Primary > Android' 카테고리의 다른 글

App Startup  (0) 2023.01.25
AndroidX Collection Library  (0) 2022.12.25
[Android Studio] Flamingo 신기능 정리  (0) 2022.12.07
[Android Studio] Electric Eel 신기능 정리  (0) 2022.12.04
[Android] 모듈화 가이드  (0) 2022.11.18
Comments