brunch

You can make anything
by writing

C.S.Lewis

by Tilltue Aug 21. 2019

iOS 오픈소스 유닛테스트 톺아보기

Alamofire, Kingfisher, promiseKit


약 5개월전, 네트워크 관련 이슈를 검색하다가 우연찮게 Alamofire PR 하나를 보게되었다.

travis-ci 에서 테스트가 실패해서 병합이 안되고있는 상황에 놓여있는 PR이었는데, 어떤 테스트인지 관심이 생겨 Alamofire 테스트 코드를 조금 살펴보았는데, 매우 촘촘하게 짜여지고 깔끔하게 잘 작성된 테스트였다.

* travis ( 오픈소스에 한해 테스트 자동화를 무료로 제공 )


이후 좀더 검색해보니, 몇몇 오픈소스들의 경우에 테스트 코드들이 작성되어있는 경우가 있었고, 

지인들과 오픈소스 테스트 코드에 대한 스터디를 진행했다. 스터디할때 정리했던 내용을 적어본다.



1. Alamofire 테스트 코드 분석

https://github.com/Alamofire/Alamofire/tree/master/Tests

- 505 개의 테스트 케이스

- XCTestsCase를 사용.

- AAA( Arrange, Act, Assert) 가 아닌 GWT ( Given / When / Then ) 패턴을 사용.

- 테스트 코드에 주석은 거의 존재 하지 않으며, 메서드 이름으로 테스트를 설명한다.

- 대부분이 비동기 테스트 코드이므로, expection fullfill, waitForExpectations 를 사용한다.

let expectation = self.expectation(description: "download should complete")

이런식으로 테스트가 기대하는 결과를 쉽게 알수있게 작성되어있다.

- 예외 (throw) 가 발생할수 있는 테스트에는 do catch 로 테스트 전체를 묶어 두었다.

- 네트워크 라이브러리 이므로 실제 네트워킹 동작이 테스트에 사용되는데 https://httpbin.org 를 사용한다.


- setup 이 같거나, 개념상 상위 클래스가 필요한 경우 상속을 사용했다.

* 인증 관련 테스트 파일(AuthenticationTests.swift)의 테스트 작성

- AuthenticationTestCase

ㄴ BasicAuthenticationTestCase (상속)

ㄴ HTTPDigestAuthenticationTestCase (상속)

위 AuthenticationTestCase 에서는 setup 만 수행하고 테스트 케이스는 없다.


Alamofire 테스트 케이스 발췌

download progress 테스트이다.

* 검증 방법으로 이전 progress 값이 다음 progress 값보다 큰걸 확인하다가 1로 종료되는것을 확인한다.


다운로드 리퀘스트시 lifetime 이벤트에 대한 테스트이다.


Alamofire 테스트 코드는 정말 깔끔하고 이해하기 쉽게 작성되어있다.

테스트를 공부하는 중이라면 꼭보자!! 두번보자!!


2. Kingfisher 테스트 코드 분석

https://github.com/onevcat/Kingfisher/tree/master/Tests

- 171 개의 테스트 케이스, 커버리지 70.6%

- AAA, GWT 패턴 둘다 사용하지 않는다.

- expection 의 description 으로 함수이름을 사용하는 과감함을 보여준다. 

* Alamofire 의 세상 친절한 description 과는 천지 차이다.

func testExtendExpirationByAccessing() {
        let exp = expectation(description: #function) <- 이것처럼
}

- http reqeust 테스트에는 Stub 을 사용했으며  https://github.com/onevcat/Nocilla.git 를 사용했다.

- 이슈 번호를 주석으로 적어둔 테스트 케이스도 있었다. 

* 이슈발생으로 추가된 회귀 테스크 케이스이려나?


Kingfisher 테스트 케이스 발췌

다운로드 task 켄슬에 대한 테스트이다.

*SUT가 무엇인지, 어디에 위치하는지 한눈에 알아보기는 힘들었지만, 

메서드 명으로 먼저 이해하고, 테스트 코드를 읽어내려가면 어렵지 않게 찾을수 있었다.

( 그래도 한눈에 들어오면 좋지 않을까? )


아래는 modifire.url 이 nil 일때 downloadimage 반환 task 가 nil 인것을 테스트 하고 있다.

Kingfisher 는 위에 작성한 비동기 테스트 방법같은 것들을 참고로 보고, 

테스트 작성은 Alamofire 를 참고 하는게 좋을것 같다. 

:)


3. promiseKit 테스트 코드 분석

https://github.com/mxcl/PromiseKit/tree/master/Tests

- 250개의 테스트 케이스, 5개의 테스트 프로젝트 타겟

- AAA, GWT 패턴 둘다 사용하지 않는다.

정리할게 특별히 없다! ;)


promiseKit 테스트 케이스 발췌


예외 처리(catch, finally ) 테스트 

helper 함수를 이해하면 무엇에 대한 테스트인지 이해하기 쉽다.


이니셜 라이저에서 throw 를 발생시킬때에 대한 테스트이다.

isRejeted 와 error 가  발생할것을 기대한다.


deinit 에 대한 테스트 코드

* 이런식으로 테스트 할수도 있구나~ 라는 생각이 들었던 테스트 코드


특정버전에서만 수행하는 테스트 코드.

이슈링크로 볼때 특정 버전에서 발생한 문제에 대한 회귀 테스트 인것 같다.

* 버전 분기를 보라... 꼼꼼도 하구나... 


promiseKit은 재밌는 테스트 코드들이 많았다.



마치며...

세가지 오픈소스의 테스트 코드를 살펴봤다.

세가지 모두 깔끔하게 작성되어있다. 하지만 테스트를 이해하기 가장 쉬웠던 코드는 Alamofire 코드였다.

나도 이렇게 깔끔하고 이해잘되게 테스트 코드 작성하고 싶다... 

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari