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

728x90

UITest

UITest는 UnitTest와 다르게 한 화면에 있는 UI의 동작을 검증하는 테스트를 작성할 수 있다.

UnitTest에선 동작별로 잘 작동하는지 테스트를 작성했다면

UITest는 화면에 들어오는 입력에 UI가 잘 존재하는지를 테스트 할 수 있다.

import XCTest

final class MyUITests: XCTestCase {

    override func setUpWithError() throws {
        continueAfterFailure = false
    }

    override func tearDownWithError() throws {
    }

    func testExample() throws {
        let app = XCUIApplication()
        app.launch()
    }

    func testLaunchPerformance() throws {
        if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
            // This measures how long it takes to launch your application.
            measure(metrics: [XCTApplicationLaunchMetric()]) {
                XCUIApplication().launch()
            }
        }
    }
}

UI Test Case 파일을 생성하면 나오는 기본 템플릿.

setup함수에 continueAfterFailure는 UITest Case가 실패한 후에도 동작을 계속 할것인지에 대해서 설정하는 것. 일반적으로 false로 해놓는걸 권장한다.

app = XCUIApplication()
app.launch()

이 두 줄은 UITest를 하기위해 테스트로 앱을 런치시키는 코드. 테스트 케이스 마다 setup이 실행되기 때문에 setup메서드에 작성해놓는것이 좋다.

setup, tearDown은 UnitTest파일과 똑같이 테스트 실행 전 setup이 호출이 되고 테스트가 종료되고 tearDown이 호출된다.

setup, tearDown은 3가지의 함수를 override 해서 쓸 수 있는데.. 각각 용도가 있다.

  1. func setUp() async throw -> 비동기로 상태를 설정해야할 때 사용
  2. func setUpWithError() throw -> 동기로 상태를 설정하는데 오류가 발생할 수 있을 때 사용
  3. func setUp() -> 동기로 상태를 설정하고 오류가 날 일 없을 때 사용

tearDown도 동일하다.

테스트메서드 작성도 함수어두에 test를 붙이면 테스트 함수로 생성이 된다.

테스트 작성

func test_navigationBarTitle_isCorrect() {
    let existNavigationBar = app.navigationBars["영화 평점"].exists
    XCTAssertTrue(existNavigationBar)
}
func test_searchBar_isExist() {
    let existSearchBar = app.navigationBars["영화 평점"]
        .searchFields["Search"]
        .exists
    XCTAssertTrue(existSearchBar)
}
func test_searchBar_CancelButton_isExist() {
    let navigatioinBar = app.navigationBars["영화 평점"]
    navigatioinBar
        .searchFields["Search"]
        .tap()
    let existSearchBarCancelButton = navigatioinBar.buttons["Cancel"].exists
    XCTAssertTrue(existSearchBarCancelButton)
}
enum CellData: String {
    case existMovie = "에이치"
    case notExistMovie = "000"
}
func test_영화가_즐겨찾기_되어있으면() {
    let existsCell = app.collectionViews
        .cells //collectionView에 특정 이름을 가진 셀이 존재하는지 확인
        .containing(.staticText, identifier: CellData.existMovie.rawValue)
        .element
        .exists
    XCTAssertTrue(existsCell, "Title이 표시된 Cell이 존재한다")
}
func test_영화가_즐겨찾기_되어있지_않으면() {
    let existsCell = app.collectionViews
        .cells
        .containing(.staticText, identifier: CellData.notExistMovie.rawValue)
        .element
        .exists
    XCTAssertFalse(existsCell, "Title이 표시된 Cell이 없음")
}

간단하게는 실행됐을 때 화면에 특정 UI가 존재하는지를 확인할 수 있고, UI에 탭, 텍스트입력, 스크롤을 하고 동작을 확인할 수 있다.

사실 스크롭, 탭, 텍스트 작성 메서드를 하나씩 작성하기 귀찮거나 양이 많을 수 있다.

그래서 녹화기능을 활용하면 더욱 쉽게 테스트 코드를 작성하고 검증할 수 있다.

red dot position

테스트 메서드를 작성하고 함수 내부에 커서를 놓은 상태에서 빨간 점(record button)을 누르면 앱이 실행되고 입력받는 동작을 코드로 표현해준다.

record uitest flow

다시 빨간점을 누르면 녹화가 종료된다. 시뮬레이터에서 가상 키보드를 사용하지 않고 물리키보드를 사용해서 그런지 SearchBar에 텍스트 필드 입력은 따로 나오지 않았다.

녹화도 조금식 오류가 있기 때문에 조금씩 수정하면서 UI테스트를 할 때 사용하면 유용할 것 같다.

KakaoIf에서 IOS UITest를 알아본 세션이 있었다.


추가로 더 봐야 할 것.

 

UITest (3) - XCUIApplication / XCUIElement / XCUIElementQuery

안녕하세요 :) Zedd입니다. 원래 오늘 UI Test에서의 Assertion에 대해서 공부하려고 했는데.. 그 전에 알아두면 좋을 개념들이 있어서 이거 먼저 보려고 합니다. 오늘은 XCUIApplication, XCUIElement 그리고 XC

zeddios.tistory.com

 

 

[번역]iOS Unit Testing, UI Testing 튜토리얼

이 글은 raywenderlich.com의 iOS Unit Testing and UI Testing Tutorial을 읽고 공부를 위해 번역했습니다. iOS Unit 테스트는 매력적이지 않지만, 테스트로 인해 흥미로운 앱이 버그가 많은 잡동사니가 되는 것을

velog.io

 

728x90