테스트 — 단위·Compose·Flow·Hilt
테스트는 "내 코드가 의도대로 도는지"를 자동으로 검증해 리팩터링·기능 추가에도 안심하게 한다. 안드로이드 테스트는 *빠른 단위 테스트(JVM)*부터 *느린 UI 테스트(기기)*까지 층이 있고, 코루틴·Flow·Compose·DI를 테스트하는 전용 도구가 있다. [andarch]의 DI·계층 분리가 테스트 가능한 코드의 토대였음을 여기서 확인한다. (출처: Android — Test apps / Testing Compose.)
테스트 피라미드 — 빠른 걸 많이
원칙 — 빠르고 안정적인 단위 테스트를 많이, 느리고 깨지기 쉬운 UI 테스트는 핵심 경로만. 비즈니스 로직을 안드로이드 의존성에서 분리([andarch Clean])하면 대부분을 JVM 단위 테스트로 빠르게 검증할 수 있다.
단위 테스트 — JUnit·코루틴·Flow
class MemberViewModelTest {
@Test fun `로드 성공시 Success 상태`() = runTest { // 코루틴 테스트
val vm = MemberViewModel(FakeRepository(success = true))
vm.refresh()
assertEquals(UiState.Success(fakeMembers), vm.uiState.value)
}
}
runTest(kotlinx-coroutines-test) — 가상 시간으로delay를 즉시 진행, 코루틴을 결정적으로 테스트.TestDispatcher— 디스패처를 주입([andsys 09])했기에 테스트에서 교체 가능(StandardTestDispatcher).- Flow 테스트는 Turbine —
flow.test { assertEquals(x, awaitItem()) }로 방출을 순서대로 검증. - 가짜(Fake) vs 목(Mock) — *가짜 구현(FakeRepository)*을 선호(실제처럼 동작, 안정적). MockK로 목도 쓰지만 과한 목은 깨지기 쉽다.
Compose UI 테스트 — semantics 기반
Compose는 시맨틱 트리를 통해 테스트한다 — 픽셀이 아니라 의미로 노드를 찾는다.
@get:Rule val composeRule = createComposeRule()
@Test fun 버튼_클릭시_카운트_증가() {
composeRule.setContent { Counter() }
composeRule.onNodeWithText("클릭 0").performClick()
composeRule.onNodeWithText("클릭 1").assertIsDisplayed()
}
onNodeWithText·onNodeWithContentDescription·onNodeWithTag(Modifier.testTag)로 찾고, performClick·performTextInput으로 조작, assertIsDisplayed·assertTextEquals로 검증한다. 접근성 시맨틱([18])이 테스트에도 쓰이는 셈.
Espresso — View 시스템 UI 테스트
기존 View 화면은 Espresso — onView(withId(R.id.button)).perform(click()). Compose와 한 테스트에서 혼용도 가능(점진 전환 중).
Hilt 테스트 — 의존성 교체
@HiltAndroidTest + 테스트용 모듈로 실제 의존성을 가짜로 교체한다 — 네트워크 대신 가짜 데이터, 인메모리 Room 등.
@HiltAndroidTest
class FlowTest {
@get:Rule val hiltRule = HiltAndroidRule(this)
@BindValue val repo: MemberRepository = FakeRepository() // 실제 대신 주입
}
테스트 가능한 설계로 되돌아보기
좋은 테스트는 좋은 설계의 결과다 — DI로 의존성 주입([andarch 05])·디스패처 주입([09])·계층 분리([Clean])·순수 함수/불변이면 테스트가 쉽다. 테스트하기 어렵다면 설계를 의심하라.
정리 — 빠른 단위 다수, UI는 핵심만
테스트의 핵심 — 단위(JVM·다수·runTest/TestDispatcher/Turbine)·통합(인메모리 Room)·UI(Compose semantics/Espresso·소수)의 피라미드, 가짜(Fake) 선호·DI로 교체(Hilt 테스트), Compose는 시맨틱으로 검증, 테스트 용이성은 DI·계층 분리·디스패처 주입의 산물. 리팩터링에 안심을 주는 안전망이 테스트다.
한 줄 요약 — 피라미드: 단위(다수·빠름)>통합>UI(소수·느림). 코루틴
runTest+TestDispatcher(주입), Flow는 Turbine, 가짜(Fake) 선호. Compose는createComposeRule+onNodeWithText/Tag·semantics, View는 Espresso. Hilt 테스트(@HiltAndroidTest·@BindValue)로 의존성 교체. 테스트 용이성=DI·계층 분리의 결과.
(출처: Android — Test your app / Testing Compose / Hilt testing / Test coroutines / Turbine.)