안드로이드 Viewmodel에 단위테스트를 적용해보는 중인데 마침 안드로이드 코드랩에서 튜토리얼을 제공하길래 따라해보며 정리해보았다.
깃허브 오픈소스 프로젝트를 바탕으로 예시 코드를 보며 Viewmodel에 대한 단위테스트 시나리오 예제들은 어떤 식인지 참고하기 좋았다.
이 포스팅에는 본격적인 테스트작성 전에 알고 가면 좋을 것들을 정리했다.
테스트는 성공 경로, 오류 경로, 경계 사례라는 3가지 시나리오로 분류할 수 있다.
예외나 오류 조건이 없는 흐름. 긍정적인 흐름의 기능 테스트에 집중한다.
부정적인 흐름의 기능 테스트이다. 앱이 오류 조건 또는 잘못된 사용자 입력에 어떻게 응답하는지 확인하는 데 초점을 맞춘다.
일반적으로, 가능한 모든 오류 경로를 나열하고 이에 관한 테스트를 작성하면서 다양한 시나리오에 대한 단위테스트를 계속 개선하는 것이 좋다.
앱의 경계 조건을 테스트하는 데 초점을 맞춘다.
- 집중
클래스 또는 메서드과 같은 단위를 테스트하는 데 중점을 두어야 한다.
테스트 범위를 좁히고, 개별 코드의 정확성을 검증하는 데 집중하자.- 이해 가능
코드를 읽을 때 테스트의 의도를 한눈에 파악할 수 있을 정도로 간단하고 이해하기 쉬워야 한다.- 확정성
일관되게 통과하거나 실패해야 한다. 코드를 변경하지 않고 여러 번 실행했을 때 테스트의 결과가 동일해야 한다.- 독립형
사람이 상호작용하거나 설정할 필요가 없으며 개별적으로 실행된다.
thingUnderTest_TriggerOfTest_ResultOfTest 형식을 사용해서 테스트 함수이름을 지정했다.
class GameViewModelTest {
private val viewModel = GameViewModel()
@Test
fun gameViewModel_CorrectWordGuessed_ScoreUpdatedAndErrorFlagUnset() {
}
}
테스트에서 viewmodel을 아래와 같이 초기화하면 테스트 메서드가 실행되는 동안 viewmodel을 2번 재사용되는 거 아닌가 생각할 수있다.
class GameViewModelTest {
private val viewModel = GameViewModel()
@Test
fun gameViewModel_Initialization_FirstWordLoaded() {
val gameUiState = viewModel.uiState.value
...
}
@Test
fun gameViewModel_CorrectWordGuessed_ScoreUpdatedAndErrorFlagUnset(){
...
}
}
하지만 아니다. 기본적으로 JUnit4은 각 테스트 메서드가 실행되기 전에 테스트 클래스의 새 인스턴스를 만든다. GameViewModelTest에 2개의 테스트 메서드들이 있으므로 GameViewModelTest는 2번 인스턴스화되고, 각 인스턴스에는 viewModel 속성의 자체 사본이 있기 때문에 부작용이 없으며 테스트 실행 순서는 중요하지 않다.