RxTest 와 RxBlocking 알아보기 (XCTest)
RxSwift를 도입하고 기존 클로저 기반으로 작성되었던 코드를 리팩토링하면서
기존에 작성된 테스트 코드도 Rx 기반으로 변경이 필요한데 이를 학습해보고자 함.
RxSwift를 도입하면서 어떻게 테스트할지 고민이었는데 해당 내용을 통해 개념 정리
RxTest란?
RxTest는 RxSwift Unit Test를 작성하기 위한 테스트 유틸리티 라이브러리.
RxSwift는 비동기적이고 스트림 기반으로 동작하기 때문에, 단순히 값 비교로는 테스트하기 어려움.
RxTest는 가상의 시간(Time) 과 이벤트 기록(Recorded Event) 개념을 도입해 Observable의 동작을 예측 가능하고 재현 가능한 형태로 검증할 수 있게 도움.
Observable의 가상의 시간 개념을 주입해서 테스트하는 방법으로 가상의 시간이 다 흐를때까지 기다린 후에 이벤트를 반환
각 초에 문자하나 방출한다고 가정
1초 -> "A"
2초 -> "B"
3초 -> "C"
// 2sec에 B가 나왔는지 검증
RxTest 샘플 코드
Hot Observable이랑 Cold Observable에 대해서 개념을 학습했었는데 이는 테스트 코드를 작성할 때 개념이 명확하게 필요함.
// 가상의 시간 흐름 생성
let scheduler = TestScheduler(initialClock: 0)
// 원하는 시점에 Event가 발생하는 Observable 생성(구독 여부와 관계없이 이벤트 발생)
let obsevable = scheduler.createHotObservable([
.next(1, "A"),
.next(2, "B"),
.next(3, "C")
])
// 원하는 시점에 Event가 발생하는 Observable 생성(구독이 시작되어야 정해진 순서대로 이벤트 발생)
let obsevable = scheduler.createColdObservable([
.next(1, "A"),
.next(2, "B"),
.next(3, "C")
])
// String을 관찰하는 Observer 생성
let observer = scheduler.createObserver(String.self)
// 관찰자를 통해서 테스트하고자 하는 옵저버블 구독
obsevable
.subscribe(observer)
.disposed(by: bag)
// 관찰시작
scheduler.start()
// Nimble 문법을 활용한 Test Assertion
expect(observer.events).to(
equal([
.next(1, "A"),
.next(2, "B"),
.next(3, "C")]
)
RxBlocking이란?
RxBlocking은 RxSwift의 비동기 코드를 “동기적(Synchronous)”으로 테스트할 수 있게 해주는 라이브러리.
보통 RxSwift의 Observable은 비동기로 동작하기 때문에 XCTest에서 값을 직접 비교하거나 XCTAssertEqual로 바로 검증하기 어려움.
이때 RxBlocking을 사용하면 Observable을 Blocking (즉, 멈춰서 결과를 기다리는) 형태로 변환하여 비동기 코드를 동기적으로 다룰 수 있음.
Observable의 이벤트 방출하고 특정 시간동안 방출된 Observable의 이벤트를 검증
> RxTest에 있었던 스케줄러란 개념은 없음
각 초에 문자하나 방출한다고 가정
1초 -> "A"
2초 -> "B"
3초 -> "C"
// ["A","B","C"]
RxBlocking 샘플 코드
Hot Observable이랑 Cold Observable에 대해서 개념을 학습했었는데 여기서도 매우 유용함.
아래 코드에서 complete가 되지 않도록 하려면 `.toBlocking(timeout: 2)`이런식으로 인자값을 주면 가능.
// Observable -> BlockingObservable
let obsevable = Observable.of("A","B","C").toBlocking()
// Observable의 .next 이벤트를 Array로 전환
let values = try! observable.toArray() // 어레이 전환이 컴플릿 될 때까지 대기
// Nimble의 문법 활용한 Test Assertion
expect(values).to(equal(["A","B","C"]))
단순히 방출되는 값만 필요하다면 RxBlocking으로도 충분하고
스케줄러의 개념이 들어가야한다면 RxTest를 활용하는 것이 좋다.
RxTest 와 RxBlocking 표로 정리
| 테스트 방식 | 가상의 시간 기반 (비동기 시뮬레이션) | 실제 블로킹 기반 (동기적 실행) |
| 사용 목적 | 이벤트 타이밍·순서 검증 | 최종 결과 값 검증 |
| 적합한 상황 | 스트림의 동작 과정을 세밀히 확인할 때 | Observable의 결과 값만 중요할 때 |
| 예시 | .next 발생 순서 테스트 | .toArray()로 결과 확인 |
'apple > Testing, Xcode, Environment' 카테고리의 다른 글
| Test Double (Swift) (0) | 2023.01.09 |
|---|---|
| [XCTest] XCTest에 대해서 알아보기 1편 (0) | 2022.07.03 |
| XCTest Stubber (0) | 2022.02.20 |
| [XCTest] Quick 과 Nimble에 대해서 알아보자. (0) | 2022.02.20 |
| [XCTest] 🧑🏻💻 Xcode 기존 프로젝트에 XCTest 작성 파일 추가하기! (0) | 2022.02.15 |