본문 바로가기
Xcode/Swift - PlayGround

PlayGround) RxTest에서 Timer들어간 Observable 테스트

by 후르륵짭짭 2022. 4. 24.
728x90
반응형

housetenbo(17)

 

안녕하세요. 후르륵짭짭입니다.

요즘 사내에서 테스트 코드를 작성하고 있습니다.

그런데 특정 작업 때문에 Rx Observable.create 내부에 Timer가 들어갔는데,

해당 부분은 테스트를 어떻게 해야할지 모르겠더라구요 ㅠ ㅠ

그래서 이번에 하나씩 적어보려고 합니다.

( 그리고 이제 혹시 저작권에 걸릴까봐 대표사진은 이전에 찍었던 풍경 사진을 담아야 할 것 같습니다 ㅎㅎㅎㅎ)

 

** RxSwift의 테스트의 기본 **

보통 MVVM의 코드 아키텍처를 사용하면 Input , Ouput을 정의합니다.

그리고 ViewController에서 Input을 주고 ViewModel에서 Input에 대한 값을 로직을 통해 결과를 반환하고

ViewController에서 Ouput을 받아서 사용자에게 보여줍니다.

즉, 하나의 Stream(흐름)을 viewController -> ViewModel -> ViewController로 되게 됩니다.

그런데 매번 Input, Output을 정의하는건 알겠는데, 이걸 왜 항상 이렇게 만들어야하지? 생각했습니다.

이게 필요한 이유가 Test를 용이하게 위해 구분 됐다고 생각 됩니다.

 

Input, OutPut에 대한 정의를 계속 바뀔 수 있습니다. 하지만 필수적은 로직은 통일성을 가져야한다 생각합니다.

그래서 ViewModel에 로직이 들어가고 이 ViewModel을 실제로 테스트하는게 중요합니다.

테스트를 할 때 Mock 데이터를 만들어서 테스트를 주로하지만,

ViewModel 만큼은 실제 사용하는 객체로 테스트 할 필요가 있다 생각합니다.

( 제 개인적 생각 입니다만,,, )

 

** RxBlocking ** 

RxBlocking은 쉽게 테스트할 수 있게 만들어진 Rx Testing API 입니다.

정말 쉽게 테스트 할 수 있습니다.

Subscribe 자체가 Blocking이 되는 것이다. 

하지만! Observable이나 BehaviorSubject와 같이  기본값이 탑재되어 있는 경우에는 좋게 사용할 수 있지만

위와 같이 4개의 케이스에 대해서는 사용하기 어렵습니다.

1. RxBlocking은 유한한 순서를 가졌기 때문에 마지막과 첫번째 결과에 대해서는 사용할 수 있지만, 여러 순서를 가진 경우는 RxBlocking이 유용하지 않습니다.

2 , 3. 만약에 긴 시간의 Delay가 필요하다면 RxBlocking은 현재 쓰레드를 잠그고 있어서 유용하지 않습니다.

4. 만약 비동기적 작업의 Input이 있다면 RxBlocking은 사용하기 어렵습니다.

 

즉,  Input Output이 모두 Subject로 구성된 경우 테스트로 사용하기 어렵습니다.

 

 

그래서 하나의 순서로 제공 되는 Observable 같은 경우 유용하게 사용할 수 있습니다.

 

** RxTest ** 

RxTest는 가상의 시간의 스케줄러를 사용한 테스트 방식 입니다.

위의 코드를 보면 일단 테스트용 스케줄러를 통해 결과값의 Observer를 생성해줍니다.

그리고 OutPut 결과를 방금 만든 Observer로 적용 시킵니다.

그리고 해당 Output결과는 event로 결과가 나오고 우리는 그 event 결과를 테스트 하게 됩니다.

이제 Input을 정의 할겁니다.

Input은 ColdObservable로 통해 Input값들을 (시간, 값)으로 Input Subject에 전달해줍니다.

마지막은 스케줄러를 돌려줘서 해당 테스트를 작동 시킵니다.

 -  RxTest의 ColdObservable과 HotObservable의 자세한 내용 

https://minsone.github.io/programming/reactive-swift-unit-test-1

 

[ReactiveX][RxSwift]Unit Test 1 - 핫 옵저버블과 콜드 옵저버블

여러 이벤트들이 발생할 때, 제대로 파악하지 못한다면 흐름이 뒤엉켜 내가 원하는 작업을 제대로 수행하지 못합니다. 기존에 작성하던 방식대로 내가 흐름을 제어하면 괜찮지만, Rx에 일임하여

minsone.github.io

 

** Timer가 들어간 Observable을 테스트하는 방법 ** 

self.goInput.flatMap { _ -> Observable<String> in
      return self.makeDelay()
    }
    .bind(to: self.goOutput2)

위와 같이 특정 시간 후에 방출하는 Observable을 사용하고 있을 때, 일반적인 방법으로 RxTest와 RxBlocking으로 테스트 할 수 없습니다. 

왜냐하면 Test할 때 Thread와 Observable에서 방출할 때 사용하는 Thread가 일치하지 않기 때문 입니다.

그래서 어떠한 방법을 사용허더라도 값 방출이 되지 않습니다.

따라서 모든 스케줄러를 동일하게 해줄 방법이 필요합니다. 

 

그래서 Timer Observable을 사용하고 scheduler를 주입받는 방식으로 변경해야합니다.

위와 같이 scheduler를 주입받는 방식을 사용하면 RxTest로 Timer가 들어간 Observable를 테스트 할 수 있게 됩니다.

 

참고 사이트 : 

RxSwift 테스트 튜토리올 : 

https://www.raywenderlich.com/7408-testing-your-rxswift-code

 

Testing Your RxSwift Code

In this tutorial, you’ll learn the key to testing RxSwift code. Specifically, you’ll learn how to create unit tests for your Observable streams.

www.raywenderlich.com

https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/16-testing-with-rxtest

 

RxSwift: Reactive Programming with Swift, Chapter 16: Testing with RxTest

For all the reasons why you started reading this book and are excited to begin using RxSwift in your app projects, RxTest (and RxBlocking) may very soon have you excited to write tests against your RxSwift code, too.

www.raywenderlich.com

 

RxTest 한국어 간단 내용 정리 

https://zeddios.tistory.com/996

 

RxTest

안녕하세요 :) Zedd입니다. RxTest에 대해 공부를 해보려고...합니다.. https://github.com/ReactiveX/RxSwift/blob/master/Documentation/UnitTests.md ReactiveX/RxSwift Reactive Programming in Swift. Contri..

zeddios.tistory.com

 

RxTest 참고 코드 :

https://betterprogramming.pub/rxswift-unit-testing-explained-in-3-minutes-c024b7a26d

 

RxSwift Unit Testing Explained in 2 Minutes

Using RxTest and RxBlocking libraries

betterprogramming.pub

http://adamborek.com/rxtests-rxactionsheet/

 

RxTest - How to test the Observable in Swift - Code in a suit

If you use RxSwift or not you should always write unit tests. In this article I'll show you how to tests the Observables with RxTest. Enjoy :)

adamborek.com

RxSwift 뱅크샐러드 내용 정리 - 다시 보기 :

https://www.slideshare.net/ssuser750dc6/rxswift-testing-feat-rxblocking-rxtest-192641266

 

RxSwift Testing 같이 시작하기 feat. RxBlocking, RxTest

RxBlocking과 RxTest를 통해 RxSwift를 테스트하는 법을 간단하게 알아봅시다.

www.slideshare.net

https://github.com/ReactiveX/RxSwift/blob/0b66f666ba6955a51cba1ad530311b030fa4db9c/Tests/RxSwiftTests/Observable%2BSubscriptionTest.swift

 

GitHub - ReactiveX/RxSwift: Reactive Programming in Swift

Reactive Programming in Swift. Contribute to ReactiveX/RxSwift development by creating an account on GitHub.

github.com

RxSwift 비동기 테스트 : 

https://jisoo.net/2018/03/21/iOS-Asynchronous-test.html

 

iOS 비동기 코드에 대한 테스트 방법

비동기(Asynchronous)를 테스트 하기 위한 방법들을 정리해봅니다. XCTestCase, Quick & Nimble, Rx를 다룰것이며, 더 좋은 테스트 방법들이 많이 공개되어있으니, 참고용으로 보면 좋겠습니다. 해당 게시글

jisoo.net

 

https://stackoverflow.com/questions/50217376/rxswift-tests-with-rxblocking-do-not-end

 

RxSwift, tests with RxBlocking do not end

I'm trying to test a very simple view model: struct SearchViewModelImpl: SearchViewModel { let query = PublishSubject<String>() let results: Observable<BookResult<[Book]>>...

stackoverflow.com

 

RxSwift Timer Delay 주는 방법 :

https://stackoverflow.com/questions/58691470/how-to-put-delay-in-rxswift

 

How to put delay in RxSwift?

I have an Observable to perform some task and I want it to give me result after 5 seconds but it gives me before that and sometimes after 5 seconds depending upon the complexity. For example: If...

stackoverflow.com

https://rldd.tistory.com/139

 

[week7] ⏰ Time Based Operators(cold? hot?)

✅ 이번 시간에는 시간과 관련한 오퍼레이터들을 볼 예정이야. 일부는 이전 포스팅에서 이미 사용했던 것들이지만, 재점검 할겸 중복될 수 있어. 실습 코드 https://github.com/lgvv/MyRxSwift lgvv/MyRxSwift

rldd.tistory.com

https://leechamin.tistory.com/541

 

[RxSwift] Operators - Interval, timer

Creating에 속하는 Interval operator에 대해서 알아볼 것이다. Interval 1. 정의 주어진 시간 간격을 두고 주기마다, emit되는 옵저버블을 생성한다. Interval 연산자의 경우 completed 되지 않고, 무한한 시퀀스.

leechamin.tistory.com

 

RxSwift 스케줄러 정리 :

https://sweepty.medium.com/rxswift-scheduler-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-f2e26aeb829d

 

[RxSwift] Scheduler 제대로 알아보기

내가 이해를 못해서 알아본 observeOn과 subscribeOn

sweepty.medium.com

 

728x90
반응형

댓글