[Android] Jetpack Compose 테스트코드 어떻게 짜는거예요?
지난번에는 간단하게 compose상 UI 테스트 코드를 어떻게 짜는지
맛을 봤습니다.
이번엔 제가 만든 앱을 바탕으로 테스트 코드를 짜는 과정을
포스트 하도록 하겠습니다.
이 앱은 제가 파일 탐색기에대해 조사하는겸 간단하게 만든 샘플 앱입니다.
이 앱의 UI를 테스트 해보기로 합시다!
상태
파일리스트
버튼
Column(
Modifier
.fillMaxSize()
.background(Color.White)
) {
val modifier = Modifier.weight(1f)
StatusView(
Modifier,
isMultiple,
viewModel.uploadProgress.collectAsState(),
viewModel.uploadSize.collectAsState(),
viewModel.uploaded.collectAsState()
)
FileListView(viewModel.fileList, modifier, viewModel.fileIndex.collectAsState())
ButtonMenuView(
{ viewModel.changeState(it) },
isSending,
{ viewModel.sendFile(context.contentResolver) },
{ viewModel.cancel() },
{ viewModel.showInfo() },
{ viewModel.deleteFileList() },
navHostController
)
}
화면을 굉장히 직관적으로 나눠봤습니다.
Column 안에 View를 3개 쫘라락~ 한게 끝입니다.
UI 컴포넌트별로 테스트를 짜면 딱이겠죠?
private val safViewModel = SAFViewModel()
@Test
fun `파일_선택_옵션을_클릭_한다`() {
composeRule.onNodeWithTag("file_option").assertExists()
composeRule.onNodeWithTag("file_option").performClick()
composeRule.onNodeWithTag("file_option").assertIsOn()
}
@Test
fun `텍스트가_표시_되는지_확인_한다`() {
composeRule.onNodeWithText("Selected Files").assertExists()
composeRule.onNodeWithText("uploadProgress : ${safViewModel.uploadProgress.value} %")
.assertExists()
composeRule.onNodeWithText("uploadSize : ${safViewModel.uploadSize.value} / ${safViewModel.uploaded.value} byte")
.assertExists()
composeRule.onNodeWithText("파일 다중 선택").assertExists()
}
이 두가지를 테스트 하도록했습니다.
@Test
fun `파일리스트가_비어_있어야_한다`(){
composeRule.onNodeWithTag("empty").assertIsDisplayed()
}
@Test
fun `파일리스트에_파일을_넣는다`(){
composeRule.onNodeWithTag("empty").assertIsDisplayed()
safViewModel.fileList.add(dummyItem1)
composeRule.onNodeWithTag("file_list").assertIsDisplayed()
composeRule.onNodeWithTag("file_name",useUnmergedTree = true).assertIsDisplayed()
}
@Test
fun `파일을_클릭하면_삭제된다`(){
safViewModel.fileList.add(dummyItem1)
composeRule.onNodeWithTag("file_item").assertIsDisplayed()
composeRule.onNodeWithTag("file_item").performClick()
composeRule.onNodeWithTag("empty").assertIsDisplayed()
}
@Test
fun `파일리스트를_스크롤한다`(){
repeat(5){
safViewModel.fileList.add(dummyItem1)
}
safViewModel.fileList.add(dummyItem2)
composeRule.onNodeWithTag("file_list").assertExists()
composeRule.onNodeWithTag("file_list").performScrollToIndex(4)
composeRule.onNodeWithText(Util.extractLastPathComponent(dummyItem2.displayName)).assertIsDisplayed()
}
@Test
fun `버튼이_표시되는지_확인한다`() {
composeRule.onNodeWithText("파일 선택").assertIsDisplayed()
composeRule.onNodeWithText("전체 삭제").assertIsDisplayed()
composeRule.onNodeWithText("폴더 전체 선택").assertIsDisplayed()
composeRule.onNodeWithTag("button_view").performScrollToNode(hasText("로그 보기"))
composeRule.onNodeWithText("파일 보내기").assertIsDisplayed()
composeRule.onNodeWithText("로그 보기").assertIsDisplayed()
}
@Test
fun `파일보내기_버튼을_누른다`() {
composeRule.onNodeWithText("파일 보내기").performClick()
composeRule.onNodeWithText("취소").assertIsDisplayed()
}
@Test
fun `전체_삭제_버튼을_누른다`() {
safViewModel.fileList.add(dummyItem1)
composeRule.onNodeWithText(
Util.extractLastPathComponent(safViewModel.fileList[0].displayName),
useUnmergedTree = true
).assertIsDisplayed()
composeRule.onNodeWithText("전체 삭제").performClick()
composeRule.onNodeWithTag("empty").assertIsDisplayed()
}
지난번에 이어 compose 테스트 코드에 대해 다뤄봤습니다.
테스트 코드를 읽어 보셨으면 느끼셨을텐데
테스트 케이스 써둔걸 그대로 코드로 옮긴 것 뿐입니다.
compose는 테스트 코드 짜는 방식이 굉장히 직관적이어서
짜기 편합니다.
이 글을 읽으신 독자 분들도 자신이 짠 UI를 한번 테스트 해보세요!
조금만 짜보면 바로 이해갑니다.
공부 하실 때 compose test cheatsheet를 꼭 보세요!!!
https://github.com/lyh990517/saftest
https://developer.android.com/jetpack/compose/testing-cheatsheet?hl=ko