감자주먹밥

XCTest 프로젝트 TestCode 작성&검증 (Unit Test) 본문

IOS/Test

XCTest 프로젝트 TestCode 작성&검증 (Unit Test)

JustHm 2023. 1. 28. 14:17
728x90

Test?

작성한 코드가 의도한대로 작동하는지 검증하는 과정

  • UI 표시
  • UI Layout 설정
  • API Request
  • UserDefaults 저장/가져오기 등

테스트 종류

  • Unit Test - 특정 함수, 메소드의 동작에 대한 테스트 (오늘 알아볼 것)
  • UI Test - UI 표시 / UI Action에 대한 테스트

Test Coverage

XCTest 프레임워크를 사용해서 테스트를 작성할 수 있다.

테스트 작성 % 도 TestCoverage로 볼 수 있다.

TestCoverage - Project에서 몇%의 코드에 대해서 테스트가 작성되어 있는지 나타낸 숫자.

사용방법은 간단하다. Edit Scheme에서 Test > Options에 Code Coverage 체크 끝.

TestCoverage 사용 - App의 안정성을 확인하는 기준 (50%라면.. 프로젝트의 코드 중 50%는 테스트 코드가 작성되어 있고 안정되어 있다 라고 알 수 있다.)

테스트 작성

테스트 생성

프로젝트를 처음 생성할 때 테스트를 선택하고 생성할 수 있지만, 테스트를 포함하지 않고 생성했을 경우는 새로 테스트 타겟을 만든다.

네비게이터에 Test탭이 선택되어 있어야만 +를 눌렀을 때 Test Target을 생성할 수 있다.

UnitTest Case Calss 파일을 생성하면 XCTest를 포함한 XCTestCase Class 가 생성된다.

import XCTest

final class hrlll: XCTestCase {

    override func setUpWithError() throws {}

    override func tearDownWithError() throws {}

    func testExample() throws {}

    func testPerformanceExample() throws {
        self.measure {}
    }

}

그냥 Swift 파일에 XCTestCase를 서브클래싱 해도 테스트 파일로 만들 수 있다.

먼저 setup과 tearDown이 override 되어 있는데 

setup은 각 테스트를 실행하기 전 실행되는 메서드다.

tearDown은 각 테스트가 끝나고 실행되는 메서드다.

테스트 메서드의 규칙은 메서드 이름 앞에 test를 붙여주면 테스트가 가능한 메서드로 바뀌게 된다. 

테스트 메서드 작성에는 3가지 단계로 작성할 수 있다.

  1. Arrange - 테스트에 필요한 종속성을 생성하기.
  2. Act - 테스트를 할 메서드 호출
  3. Assert - 테스트 한 메서드를 확인해 성공 유무를 확인.

먼저 간단한 테스트 작성. 왼쪽 오른쪽 버튼을 눌러 page를 증감 시키고 테스트 하는 코드를 작성해 봤다.

테스트할 타겟은 먼저 setup에서 생성을 해주고 해제는 tearDown에서 해주었다.

UnitTest, Presenter, ViewController 코드

final class MVPTestTests: XCTestCase {
    var sut: Presenter!
    var viewController: MockViewController!
    override func setUpWithError() throws {
        viewController = MockViewController()
        sut = Presenter(viewController: viewController)
    }
    
    override func tearDownWithError() throws {
        viewController = nil
        sut = nil
    }
    
    func test_tapLeft() {
        let page = sut.page
        sut.didTapLeftButton()
        if page == 1 {
            XCTAssertEqual(sut.page, page)
        } else {
            XCTAssertEqual(sut.page, page-1)
        }
    }
    
    func test_tapRight() {
        let page = sut.page
        sut.didTapRightButton()
        XCTAssertEqual(sut.page, page+1)
    }
}

테스트 함수를 보면 page를 먼저 입력받고 테스트 할 타겟의 메서드를 호출해 페이지가 잘 넘어갔는지 확인하는 코드다.

테스트 작성이 끝나면 테스트메서드 옆의 마름모 모양을 눌러 각각 실행시키거나 테스트 클래스 옆의 마름모를 눌러 전체를 테스트 해볼 수 있다.

또는 테스트 네비게이터에서도 클릭을 해 실행해볼 수 잇다.

위에서 Test Coverage를 설정해놓는 걸 알아봤었는데 Test Coverage를 포함해 빌드나 로그를 볼 수 있는 곳은 Navigator의 가장 우측 Report Navigator에 있다.

XCTAssertTrue, False, NotNil 등 값을 비교하거나 에러를 반환했는지 안했는지 등 다양한 함수로 테스트 검증을 할 수 있다.

여기서 바로 실행이 되지 않고 시간이 좀 걸리는 클로저나 다른 큐에서 실행되는 함수를 테스트 할 때는 XCTestExpectation을 사용해 검증할 수 있다.

 

func test_viewDidLoad() {
        var resultOfTask: String?
        let expectation = XCTestExpectation(description: "APIPrivoderTaskExpectation")
        
        sut.viewDidLoad()
        
        Service().request(page: sut.page) { result in
            resultOfTask = result
            expectation.fulfill() // 작업 완료 알림.
        }
        
        wait(for: [expectation], timeout: 5.0) // 이 위치에서 작업이 완료될 때 까지 최대 5초 동안 대기.
        
        XCTAssertTrue(viewController.isCalledSetupViews)
        XCTAssertNotNil(resultOfTask) // 성공
    }

XCTestExpectiation을 생성하고 실행하는 함수의 클로저가 제대로 호출 됐을 때 fulfill()을 호출해 작업 완료를 알릴 수 있다.

wait 함수를 사용해 expectation을 지정한 시간만큼 기다렸다가 검증을 하게 된다.


사실 네트워킹 테스트는 실제 서비스에서 사용하는 코드를 그대로 갖다 사용하는 것 보다 따로 Mock을 만들어 테스트를 하는 것이 좋다.

Mock을 따로 만드는 것은 네트워크 코드 말고도 검증할 타겟은 Mock으로 만들어 검증하는 것이 좋은 방법이기도 하다.

 

[Swift] Mock 을 이용한 Network Unit Test 하기

URLSession 과 URLSessionDataTask 의 Mock 을 이용해보자

sujinnaljin.medium.com

여기에서 자세히 알려주고 있다.

그 외에 블로그 글 들

 

TDD와 Xcode에서 XCTest 활용하기

TDD(Test Driven Development) 테스트 주도 개발은(TDD)은 매우 짧은 개발 사이클을 반복하는 software 개발 프로세스 중 하나이다. 개발자는 새로운 함수를 정의하는 자동화된 TestCase를 먼저 작성한다.

velog.io

 

 

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

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

jisoo.net

Quick, Nimble 같은 서드파티 테스트 도구를 사용하는 것도 나와있다.

 

소프트웨어 테스팅과 스위프트에서의 Unit Testing

소프트웨어 테스팅에 대한 기초 개념부터, 스위프트에서의 유닛 테스트 방법에 대해 정리합니다.

seizze.github.io

 

728x90

'IOS > Test' 카테고리의 다른 글

BDD 행동 주도 개발  (0) 2023.02.02
TDD 테스트 주도 개발  (0) 2023.02.02
XCTest 프로젝트 TestCode 작성&검증 (UI Test)  (0) 2023.02.01
Comments