샘성의 iOS 개발 일지

[XCTest] Unit Test작성하기 (feat. RxSwift) 본문

iOS/ReactiveX

[XCTest] Unit Test작성하기 (feat. RxSwift)

SamusesApple 2023. 7. 1. 13:12
728x90

1. Unit Test란?

  가장 작은 단위의 테스트로, 앱의 동작을 위해 작성한 코드(기능) 1개가 의도대로 잘 작동하는지 검증하는 것을 목적으로 둔다.

 

 

 

2. Unit Test의 필요성?

   물론, Unit Test를 하지 않고 시뮬레이터나 실 기기로 돌리면서 디버깅 코드를 통해 테스트를 할 수도 있다. 작은 앱이라면 오히려 이러한 방법이 더 유리한 경우도 있다. (테스트 코드 작성 시간이 더 걸리는 경우)

 

   하지만 앱의 규모가 커질수록 Unit Test의 중요성은 커진다. 앞서 말한 방식대로 규모가 있는 앱, 혹은 앞으로 확장될 앱을 테스트한다고 가정해보자. print문 등을 사용하여 콘솔창에 찍어내야할 뿐만 아니라 앱의 크기가 확장될수록 테스팅 시간도 늘고 필요하지도 않은 서버와의 통신까지 해야하는 경우까지 생기게 된다.

 

  반면에 Unit Test를 하면 특정 기능이 의도대로 잘 작동하는지만 검증할 수 있기 때문에 불필요한 테스트 비용 및 시간을 절약할 수 있다. 새로운 기능을 추가할 때, 해당 기능에 대한 Unit Test만 진행하면 되기에 수시로 빠르게 테스트하여 점검할 수 있기에 매우 편리하다.

 

 

 

3. Unit Test 작성 원칙 (FIRST)

  1. Fast: 테스트는 빠르게 동작해야 한다.

  2. Independent: 한 번에 하나의 기능에 대한 테스트만 수행한다. (각 테스트 케이스는 분리되어야 함)

  3. Repeatable: 언제든지 반복해서 테스트가 가능해야 한다.

  4. Self-Validating: 테스트에 대한 결과값은 Bool 타입으로 성공, 실패 여부를 자체적으로 판단할 수 있어야 한다.

  5. Timely: 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.
    (Production 코드 실행 이전에 유닛 테스트 먼저 구현 및 실행해야함)

 

 

4. Unit Test 진행 방식

   1. 테스트 하고자 하는 주요 대상 선정 (SUT - System Under Test)  

     일반적으로 MVVM 패턴에서  비즈니스 로직을 가진 ViewModel이 테스트 대상(SUT)이 되는 경우가 많다.
   의존성 주입(DI)이 잘 되어있다면 Mock 객체 생성하여 ViewModel을 테스트 하기에 용이하다.

  2. 테스트 케이스 작성 및 실행 (GWT)

  • Given: 테스트 준비 과정
    - Mock 객체 생성, 입력값 정의 등

  • When: 테스트 코드 실행 (메서드 호출)

  • Then: 실행된 테스트에 대한 검증 (리턴값에 대한 검증)


* 예시

// SUT - System Under Test
    private var sut: CalculatorViewModel! // ViewModel의 기능을 테스트 하기에 SUT로 지정
    private var disposeBag = DisposeBag()
    
    override func setUp() {
        sut = CalculatorViewModel()
        super.setUp()
    }
    
    override func tearDown() {
        super.tearDown()
        sut = nil
        disposeBag = DisposeBag()
    }
    
// MARK: - TestCode
    	/* testCase 1 :
              - total : 1000,
              - personCount: 4
    	 */
    func testResultWithtotal1000and4person() {
        // Given - 가상의 데이터 생성
        let total: Int = 1000
        let personCount: Int = 4
        
        // When - 해당 데이터에 대한 output 생성
        let output = sut.transform(input: viewModelInput(total: total,
                                                         personCount: personCount))
        // Then - 해당 데이터에 대한 output이 예상과 일치한지 검증
        output.resultObservable
            .bind { result in
                XCTAssertEqual(result.totalAmount, 1000) // 1000과 일치한지
                XCTAssertEqual(result.personCount, 4) // 4와 일치한지
                XCTAssertEqual(result.amountPerPerseon, 250) // 250과 일치한지
            }.disposed(by: disposeBag)
    }

 

728x90

'iOS > ReactiveX' 카테고리의 다른 글

ReactorKit Unit Test하기  (0) 2023.07.04
ReactorKit을 MVVM에 넣어보기  (0) 2023.07.02
네이버 검색 API 사용하기 (feat. RxSwift, Alamofire)  (0) 2023.06.23