테스트 동기화

Compose 테스트는 기본적으로 UI와 동기화됩니다. ComposeTestRule를 사용하여 어설션이나 작업을 호출하면 테스트가 미리 동기화되고 UI 트리가 유휴 상태가 될 때까지 기다립니다.

일반적으로 별도의 조치를 취할 필요가 없습니다. 하지만 몇 가지 극단적 사례에 관해 알아야 합니다.

테스트가 동기화되면 Compose 앱이 가상 클록을 사용하여 시간을 앞당깁니다. 즉 Compose 테스트가 실시간으로 실행되지 않으므로 최대한 빨리 통과할 수 있습니다.

하지만 테스트를 동기화하는 메서드를 사용하지 않는 경우 리컴포지션이 발생하지 않으며 UI가 일시중지된 것으로 표시됩니다.

@Test
fun counterTest() {
    val myCounter = mutableStateOf(0) // State that can cause recompositions.
    var lastSeenValue = 0 // Used to track recompositions.
    composeTestRule.setContent {
        Text(myCounter.value.toString())
        lastSeenValue = myCounter.value
    }
    myCounter.value = 1 // The state changes, but there is no recomposition.

    // Fails because nothing triggered a recomposition.
    assertTrue(lastSeenValue == 1)

    // Passes because the assertion triggers recomposition.
    composeTestRule.onNodeWithText("1").assertExists()
}

이 요구사항은 앱의 나머지 부분이 아니라 Compose 계층구조에만 적용됩니다.

자동 동기화 사용 중지

assertExists()와 같은 ComposeTestRule을 통해 어설션이나 작업을 호출하면 테스트가 Compose UI와 동기화됩니다. 경우에 따라 이 동기화를 중지하고 클록을 직접 제어해야 할 수도 있습니다. 예를 들어 UI가 계속 사용 중일 때 애니메이션의 정확한 스크린샷을 캡처하는 시간을 제어할 수 있습니다. 자동 동기화를 사용 중지하려면 mainClockautoAdvance 속성을 false로 설정하세요.

composeTestRule.mainClock.autoAdvance = false

일반적으로 그런 다음에 직접 시간을 앞당깁니다. advanceTimeByFrame()을 사용하여 정확히 한 프레임을 앞당기거나 advanceTimeBy()를 사용하여 특정 기간만큼 앞당길 수 있습니다.

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

유휴 리소스

Compose는 모든 작업과 어설션이 유휴 상태에서 실행되도록 테스트와 UI를 동기화하여 필요에 따라 기다리거나 클록을 앞당길 수 있습니다. 하지만 결과가 UI 상태에 영향을 미치는 일부 비동기 작업은 테스트가 인식하지 못하는 동안 백그라운드에서 실행할 수 있습니다.

테스트에서 이 유휴 리소스를 만들고 등록하여 테스트 중인 앱이 사용 중인지 아니면 유휴 상태인지 파악할 때 고려할 수 있습니다. 하지 말아야 할 일 추가 유휴 리소스를 등록해야 하는 경우가 아니라면 조치를 취해야 합니다. 예를 들어, Espresso와 동기화되지 않은 백그라운드 작업을 실행하거나 편지쓰기를 클릭합니다.

이 API는 Espresso의 유휴 리소스와 매우 유사하여 테스트 대상이 유휴 상태이거나 사용 중인 경우입니다. Compose 테스트 규칙을 사용하여 IdlingResource의 구현을 등록합니다.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

수동 동기화

경우에 따라 Compose UI를 테스트의 다른 부분 또는 테스트 중인 앱과 동기화해야 합니다.

waitForIdle() 함수는 Compose가 유휴 상태가 될 때까지 기다리지만 함수는 autoAdvance 속성에 따라 다릅니다.

composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.

composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.

두 경우 모두 waitForIdle()은 대기 중인 그리기 및 레이아웃 단계도 기다립니다.

또한 advanceTimeUntil()을 사용하여 특정 조건이 충족될 때까지 클록을 앞당길 수 있습니다.

composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }

지정된 조건은 클록의 영향을 받을 수 있는 상태를 확인해야 합니다(조건은 Compose의 상태만 확인함).

조건 대기

데이터 로드 또는 Android의 측정 또는 그리기(즉 Compose 외부의 측정 또는 그리기)와 같이 외부 작업에 종속되는 모든 조건은 waitUntil()과 같이 더 일반적인 개념을 사용해야 합니다.

composeTestRule.waitUntil(timeoutMs) { condition }

다음과 같은 waitUntil 도우미를 사용할 수도 있습니다.

composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)

composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)

composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)

composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)

추가 리소스

  • Android에서 앱 테스트: 기본 Android 테스트 방문 페이지에서는 테스트 기본사항과 기법을 더 폭넓게 살펴볼 수 있습니다.
  • 테스트 기본 요소: 자세히 알아보기 Android 앱 테스트의 핵심 개념을 배웠습니다.
  • 로컬 테스트: 일부 테스트는 자체 워크스테이션에서 로컬로 실행할 수 있습니다.
  • 계측 테스트: 우수함 계측 테스트도 실행합니다 즉, 스테이트리스(Stateless) 컨테이너를 해야 합니다.
  • 지속적 통합: 지속적 통합을 통해 테스트를 배포에 통합할 수 있음 살펴봤습니다
  • 다양한 화면 크기 테스트: 사용자에게 제공할 수 있는 여러 기기이므로 다양한 화면용으로 테스트해야 합니다. 있습니다.
  • Espresso: 뷰 기반 UI용이지만 Espresso 지식은 Compose 테스트의 일부 측면에도 유용할 수 있습니다.