UIKit 환경에서 뷰 컨트롤러는 3가지 방식으로 구성할 수 있습니다.
( Xib, Storyboard, Code Base )
해당 방식으로 구성된 뷰 컨트롤러를 인스턴스화 하는 방법을 먼저 살펴보겠습니다.
뷰 컨트롤러 인스턴스 가져오기
Xib, Code Base
- 별도의 파라미터가 없는 경우 바로 인스턴스화 가능합니다.
Storyboard
- 먼저 UIStoryboard 인스턴스에 접근하고, 해당 메서드로 생성해야 합니다. 참고
뷰 컨트롤러 view 로드하기
이렇게 가져온 뷰 컨트롤러는 따로 view 를 로드하는 과정을 거쳐야 합니다.
XIB 와 Storyboard 기반의 vc 는 loadViewIfNeeded() 를 통해 Outlet 들을 구성하고 연결할 수 있게 됩니다.
Code Base 로 구성된 뷰 컨트롤러도 해당 메서드를 호출하면 viewDidLoad 도 이어서 실행되기 때문에
loadViewIfNeeded() 를 동일하게 사용할 수 있습니다.
* 다음과 같은 코드도 loadViewIfNeeded() 와 같은 동작을 합니다.
뷰 컨트롤러 view 테스트 하기
IBAction 으로 연결된 버튼을 누르면, textLabel 이 변경되는 간단한 앱을 테스트 해보겠습니다.
뷰 컨트롤러 코드는 다음과 같습니다.
그 다음 유닛 테스트에서 필요한 환경을 구성합니다.
* 1: @testable 어노테이션과 함께 import 하면 private 를 제외한 모든 요소에 접근할 수 있습니다.
* 2: sut 는 system under test 의 약어로서 테스트할 대상을 말합니다.
* 3: 유닛 테스트는 각 메서드 마다 서로 다른 인스턴스를 생성하여 테스트합니다.
즉 필요한 객체를 생성하고 해제하지 않는다면, 해당 테스트가 전부 끝날 때 까지 sut 가 메모리에 남게됩니다.
따라서 tearDown 에서 레퍼런스 카운트를 줄이는 과정이 필요합니다.
( 순서 setUp -> 테스트 메서드 -> tearDown )
위와 같이 환경을 구축하고 테스트 메서드를 작성해보겠습니다.
1. loadViewIfNeeded 를 통해 Outlet 과 Action 을 구성합니다.
2. UIButton 의 sendActions 메서드를 통해 터치 이벤트를 전달합니다.
3. XCTAssertEqual 로 값이 맞게 들어갔는지 검증합니다.
네비게이션 컨트롤러 push 테스트 하기
이번에는 버튼을 누르면 NavigationVC 에서 push 되는 상황을 테스트 해보겠습니다.
뷰 컨트롤러 코드는 다음과 같습니다.
테스트 메서드를 작성해보겠습니다.
* 1: push 와 같은 동작은 유닛 테스트 환경에서 동작되지 않을 수 있습니다. 따라서 런 루프에 있는 이벤트를
처리하기 위하여 다음과 같은 코드로 런 루프를 실행시킵니다. 이는 다른 UIKit 컴포넌트 테스트에서도 동일하게
사용할 수 있습니다.
* 2: navigation controller 는 viewControllers 를 통해 현재 가지고 있는 뷰 컨트롤러들에 접근할 수 있습니다.
따라서 count 를 통해 push 된 VC 가 있는지 파악할 수 있습니다.
연습을 마무리하며 "UITest VS Unit Test?"
View 와 관련된 요소는 UITest 를 통해서도 테스트할 수 있습니다.
다만 뷰 컨트롤러를 Unit Test 로 테스트하게 되면 다음과 같은 장점이 있습니다.
1. 테스트할 때 컨트롤러에 다른 의존성을 주입할 수 있습니다.
실제 앱의 경우 서로 다른 의존성들이 컨트롤러에 존재하게 됩니다. ( MVVM 의 경우 ViewModel )
이때 Mock 으로 구현된 객체를 주입하면 반복 가능하고 환경에 영향을 받지 않는 테스트가 가능해집니다.
2. Unit Test는 UITest 보다 속도가 빠릅니다.
속도가 빠른 이점을 이용해서 빠르게 성공/실패 피드백을 받고 이를 개발 프로세스에 적용시킬 수 있습니다.
3. 앱 시작점 부터 탐색할 필요가 없이 바로 테스트가 가능합니다.
UITest 는 앱 시작점 부터 테스트를 시작하게 됩니다.
이는 필요한 테스트 영역까지 탐색해서 들어가야 한다는 것을 말합니다.
이와 달리 Unit Test 는 필요한 객체를 생성하고 바로 테스트 할 수 있습니다.
언제 UITest 를 사용하면 좋을까?
UITest 는 End To End 테스트에 적합합니다. 사용자가 직접 사용하는 것 처럼
GUI 환경에서 시나리오, 기능 테스트를 진행하는 것을 의미합니다.
애플 WWDC 세션 자료를 참고하면 UITest 가 테스트 피라미드에 가장 높은 곳에 위치한 것을 볼 수 있습니다. 이는 Unit 테스트에 비해서 개수가 적고 변경되기 쉬우며, 통합 테스트에 가장 적합하다는 것을 말합니다.
UITest 는 다른 테스트 러너에서 실행되어서 의존성을 주입하기 어렵다는 단점이 있지만 테스트시에 앱 시작점에서 BaseURL 를 변경하고 그에 맞게 테스트 서버를 준비하면 요청을 Stub 할 수 있게 됩니다.
참고한 자료:
'iOS Dev > Testing' 카테고리의 다른 글
iOS URLSession Test Double 만들기 (0) | 2021.08.17 |
---|---|
iOS 에서 Void Observable 테스트 코드 작성하기 (0) | 2021.07.13 |