[Jetpack Compose] UI Test + API Test 를 동시에 진행하는 통합 계측테스트 진행 시 API 수신 기다리는법

오규성·2025년 11월 15일

앱 통합 테스트를 진행하면서 한 가지 문제가 생겼다.

UI Test 를 진행하는 스크린 단에서는 MainThread 가 실행되는데, API 를 호출하고 처리하는 비즈니스 로직단에서는 ViewModelScope 를 호출하여 IO Thread 를 사용하는 것이다.

@Test
fun testMain(){
    ComposeTestRule.onNodeWithText("API 호출").performClick()
    ComposeTestRule.onNodeWithTag("API 수신 성공 버튼").assertIsEnabled()
}

@Composable
fun test(viewModel: MainViewModel) {
    val boolean by viewModel.booleanStateFlow.collectAsStateWithLifecycle()

    Column {
        Text(
            modifier = Modifier.clickable {
                viewModel.setBoolean()
            },
            text = "API 호출"
        )
        Button(enabled = boolean, onClick = {}) {
            Text(text = "API 수신 성공 버튼")
        }
    }
}

만약 위와 같은 테스트 코드가 있다고 치자.
테스트 순서 상 다음과 같은 플로우를 기대하였을 것이다

  1. 노드 트리에서 API 호출 텍스트를 가진 노드를 찾아 해당 컴포저블을 클릭처리.
  2. 1번 컴포저블을 클릭하였으므로 당연히 API 수신을 확인하는 버튼의 enabled 도 True 가 될 것을 기대

하지만 위와 같은 작업을 실행한다면 결과는 실패 처리가 된다.

왜냐하면 API 는 우리가 실행하는 Test Code 의 스코프 내에서 돌아가는 작업이 아닌, 별도의 ViewModel Scope 에서 돌아가는 환경이기 때문이다.

# 그렇다면 이러한 상황에서 API 수신을 대기하기 위한 방법은 무엇이 있을까?

사실 이것에 대한 처리 방법은 생각보다 간단하다
ComposeTestRule 에서 사용 가능한 waitUntil 을 활용해주기만 하면 끝이난다.

설정해준 타임아웃 시간 내로 안의 결과값이 True 를 Return 할때까지 대기하는 함수

나의 경우 NavController.navigate 를 실행하였을때 NavController 가 현재 Route 를 벗어날 때까지 대기 상태로 만들도록 설정하였는데, API 수신의 경우 호출이 성공하였거나 실패하였을 때의 State 를 관리하는 객체를 이 WaitUntil 스코프 내에 등록 하면 자신이 원하는 상태가 되기 전까지 대기 상태로 만들어주므로, 결과가 Return 되지 않았음에도 다음 테스트 코드가 실행되는 불상사를 막을 수 있다.


UI 테스트 코드 작업 시 LaunchedEffect 가 실행이 안될 때

Android InstrumentTest 에서 UI Test 를 진행하다보면 분명 State 가 바뀜에 따라 LaunchedEffect 가 실행이 되어야하는데 실행이 안되는 경우가 존재할 것이다.

이럴 때는 ComposeTestRule.awaitIdle() 이나 ComposeTestRule.waitForIdle() 메소드를 활용하여 UI 가 안정적인 상태에 도달할 때까지 대기 상태로 만들어주면 정상적으로 실행되는 것을 확인할 수 있다.

profile
안드로이드 개발자 Gyu 의 개발 블로그 !

0개의 댓글