본문 바로가기
Android

Android UI Automator & Espresso 기반 UI 테스트

by 중곰 2024. 12. 24.

 

OverView


  • Android UI Automator & Espresso 기반 UI 테스트를 위한 기반을 정리

개념


  • UI Automator
    • Android SDK에 내장된 UI 테스트 프레임 워크
    • 앱 간 탐색 및 시스템 UI 와의 상호작용 등 앱 외부의 요소 테스트에 유용 (예 : 설정, 앱 실행, 알림 창 등)
    • 디바이스 전체를 제어 가능
  • Espresso
    • Google에서 제공하는 Android UI 테스트 프레임워크
    • 앱 내부 View 요소(버튼, 텍스트 등)와 상호작용을 자동화
    • 안정적이고 동기화된 테스트 환경을 제공
  • 차이점
    • Espresso 는 앱 내부 테스트에 특화, UI Automator는 시스템 UI를 포함한 전체 디바이스 제어 가능

 

테스트 모듈 관리 전략


  • 공통 테스트 코드를 위한 testing 모듈
    • 테스트 관련 유틸리티 (예: Fake, Mock, Test Rule) 를 공통으로 사용한다면, testing 모듈에 배치
    • shared module 로 사용되며 다른 feature 모듈에서 의존성을 추가하여 활용
    • 유틸리티성 테스트 코드나 공통적인 테스트 의종성을 여기에 정의
    • 공통적인 테스트 의존성 배치
    • dependencies {
          // 공통적으로 사용하는 Compose 테스트 라이브러리
          implementation "androidx.compose.ui:ui-test-junit4:1.0.5"
          debugImplementation "androidx.compose.ui:ui-test-manifest:1.0.5"
      
          // 공통적으로 사용하는 Espresso
          implementation "androidx.test.espresso:espresso-core:3.4.0"
      }
    • 테스트 유틸리티등 제공
    • object TestUtils {
          fun createFakeRepository(): Repository {
              return FakeRepository()
          }
      }
  • 각각의 feature 모듈에서 테스트
    • UI 관련 테스트 (Espresso/Compose))는 각 feature모듈에 작성
    • 이 방식은 테스트를 해당 모듈의 범위 내로 한정
    • 해당 모듈에서만 테스트 의존성 추가
    • dependencies {
          androidTestImplementation project(":testing") // 공통 테스트 모듈 의존성 추가
          androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.0.5"
          androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0"
      }
    • UI 테스트 및 특정 비즈니스 로직 테스트는 각 feature 모듈에서 작성
    • @RunWith(AndroidJUnit4::class)
      class FeatureXTest {
          @Test
          fun testSomeFeature() {
              // Compose or Espresso tests here
          }
      }

핵심 요소


  • UI Automator
    • UiDevice : 디바이스 제어
    • UiSelector : UI 요소를 선택
    • UiObject : 선택된 UI 요소의 동작 수행
  • Espresso:
    • onView: 특정 View를 찾음.
    • ViewMatchers: 뷰의 속성 매칭 (예: withId, withText).
    • ViewActions: 동작 수행 (예: click).
    • ViewAssertions: 결과 검증 (예: matches).
  • Compose Testing 주요 구성
    • createAndroidComposeRule: Compose 테스트 환경 설정.
    • onNodeWithText: 특정 텍스트를 가진 Compose 노드 탐색.
    • performClick: 노드에 클릭 동작 수행.
    • assertIsDisplayed: 노드가 화면에 표시되는지 검증.

간단 설명


  1. UiDevice 초기화:
    • UiDevice: 디바이스를 제어하는 핵심 객체.
    • getInstance: 현재 테스트 환경에 연결된 디바이스 객체를 가져옴.
  2. val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
  3. 홈 버튼 초기화:
    • 디바이스의 홈 화면으로 이동하여 초기 상태를 설정.
  4. device.pressHome()
  5. 앱 실행:
    • UiSelector().descriptionContains("MyApp"): 앱의 이름이나 설명으로 앱 실행기를 탐색.
    • clickAndWaitForNewWindow(): 클릭 후 새로운 창(화면)이 열릴 때까지 대기.
  6. val appLauncher = device.findObject(UiSelector().descriptionContains("MyApp")) appLauncher.clickAndWaitForNewWindow()
  7. 버튼 클릭:
    • UiSelector().text("Next"): 버튼의 텍스트가 "Next"인 요소를 탐색.
    • click(): 해당 요소를 클릭.
  8. val nextButton = device.findObject(UiSelector().text("Next")) nextButton.click()
  9. 다음 화면 확인:
    • 다음 화면의 특정 요소(예: 텍스트 "Next Screen")가 존재하는지 확인.
    • assert: 조건을 만족하지 않으면 테스트 실패.
  10. val nextScreenText = device.findObject(UiSelector().textContains("Next Screen")) assert(nextScreenText.exists())

화면 이동의 추가 고려사항

  1. 앱 내 Navigation 확인:
    • UiSelector().resourceId("com.example:id/uniqueId"): 특정 View의 리소스 ID로 탐색.
    • View의 고유 리소스를 활용해 더 안정적으로 요소 탐색.
  2. 대기 조건:
    • 비동기 작업 대기:
      • 최대 5초 동안 "Next Screen" 텍스트가 표시되기를 기다림.
    • device.wait(Until.hasObject(By.text("Next Screen")), 5000)
  3. 스크롤 필요 시:
    • 긴 목록에서 항목을 찾으려면 UiScrollable 사용:
    • val scrollable = UiScrollable(UiSelector().scrollable(true)) scrollable.scrollTextIntoView("Next")
반응형