일단 유닛테스트란 구현하는 method를 테스트하는 또 다른 method의 집합체 이다. 하나의 유닛 테스트 method는 테스트 하려고 하는 method의 특정 루틴을 검사한다. 이말은 하나의 method를 테스트 하기 위해 기본적으로 성공, 실패, 예외 등 여러 유닛 테스트 method가 필요하다.
소프트웨어 엔즈니어라면 한번쯤은 들어봤거나 당연하게 사용하고 있을것이다. 하지만, 아직 국내 작은 기업 혹은 스타트업에서는 바쁘다는 이유만으로 이를 무시하는 경우도 많다고 한다. 사실 나도 15년정도 개발자로 일하면서 TDD적용해서 개발할때를 제외하고 이를 엄격하게 지킨 경우는 그리 많지 않은것 같다. 하지만, 이를 적용했을때와 적용하지 않았을때의 소프트웨어 품질 유지 격차는 매우 컷다.
기본적으로 유닛 테스트를 통해서 method단위의 여러 경우의 수를 검증하고 릴리즈 전에 basic 한 문제의 발견해서 수정 할 수 있다.(적용후 기본적인 null point access exception 문제는 거의 사라진다...) 또한, 잘 만들어진 유닛테스트는 코드의 리팩토링에 대한 부담에서 자유롭게 해준다.
초기 MVP(Minimum Viable Product)를 target 으로 만드는게 아니라면 가급적 적용하는것이 좋다. 제품 코드라는것이 처음 시작할때에는 뭐.. 기능이 그리 많지 않으니 괜찮겠지 하고 시작하지만 1년만 지나도 눈덩이 처럼 불어난 코드와 기능들 때문에 테스트를 감당할 수 없고, 릴리즈 할때마다 메일박스에 쌓여 있는 exception 메일을 받아보고 자괴감에 빠지는 나를 발견할수도있다.
Android 에서 Unit Test를 적용 하는 방법은 많은데 이 글에서는 아래 나열된 라이브러리를 gradle dependency에 추가해서 진행할 예정이다.
dependencies{
testImplementation 'junit:junit:4.12'
testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation 'org.mockito:mockito-core:2.19.0'
testImplementation 'org.powermock:powermock-module-junit4:2.0.4'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.4'
}
뭔가 많다.... 간단하게 설명하면
이정도면 일단 기본적인 Unit Test는 가능하다.
프로젝트를 생성하면 아래와 같이 Unit Test 코드를 위치시킬 수 있는 폴더 및 default code를 확인 할 수 있다. 아래 위치에 앱의 구현코드와 동일한 package 구조를 만들고 각각의 class 마다 하나의 Unit Test Code파일을 만들면 구분/관리하기 쉽다.
이 블로그에서는 예제를 위해서 아래와 같은 folder 구조와 예제 소스 파일들을 추가 하고, 이중 Unit Test를 진행할 구현 class 가 있는 소스 파일은 WebSocketManager.java이고, 해당 구현 class 를 테스트할 Unit Test가 구현된 소스 파일은 testWebSocketManager.java를 사용해서 진행한다.