UITest는 알파벳 순서대로 진행된다. 클래스 파일 - 파일 내부 메서드 순서까지
그래서 클래스는 UnitTest_A
이런식으로 만들고 내부 메서드는 test_01_테스트이름
으로 관리했다.
앱실행
let app = XCUIApplication()
app.launch()
XCTestCase extension
- 원하는 element가 있는지 체크 후 tap할 수 있도록 XCTestCase에 extension 추가
func tap(element: XCUIElement?, timeout: Double = 1.0) {
XCTAssertTrue(element?.waitForExistence(timeout: timeout) == true)
element?.tap()
}
func checkAlert(app: XCUIApplication, string: String) {
let alert = app.alerts[string]
XCTAssertTrue(alert.waitForExistence(timeout: 1.0))
}
XCUIElementQuery extension
- firstMatch는 있는데 lastMatch는 없어서 추가
var lastMatch: XCUIElement { return self.element(boundBy: self.count - 1) }
테스트 실행
- 테스트 실행 시 내가 원하는 시나리오대로 테스트가 진행되도록 상황에 맞는 element를 누를 수 있도록 한다.
- element를 찾는 쿼리를
XCUIElementQuery
로 정의해두었다. 해당 쿼리에는 buttons, pickers, collectionviews, cells와 같이 거의 모든 ui 요소들을 검색할 수 있도록 제공된다. - 내가 원하는 특정 요소를 찾을 때는 실제 app 코드에
accessibilityIdentifier
를 설정해준다.- 만약에 특정 버튼을 찾고 싶으면
app.buttons["내가지정한 accessibilityIdentifier"]
로 검색할 수 있다.
- 만약에 특정 버튼을 찾고 싶으면
- 모든 요소가 XCUIElementQuery로 찾아지는 건 아니고 간혹 Others로 지정된 경우도 있다. 이럴땐 디버깅을 해보거나 text가 지정된 경우
staticTexts["원하는 text"]
로 검색할 수 있었다.
파일 저장 테스트
- 이게 참 오래걸렸는데.... github action 시뮬레이터에서 파일 저장이 제대로 되지 않는 이슈가 있었다.. 코드는 만들어놓고 결국 주석처리...
- 그렇지만 블로그에는 정리해두고 나중에 필요할 때 찾아보려고 한다.
- 파일 저장 화면
XCTAssertTrue(app.buttons["DOC.itemCollectionMenuButton.Ellipsis"].exists)
tap(element: app.navigationBars["FullDocumentManagerViewControllerNavigationBar"].buttons.lastMatch)
- Move 옆 버튼이 존재하는지로 파일 저장 화면이 나타났는지 체크
- 파일 저장 화면의 Navigation이름이
- Move 버튼은 NavigationBarButton의 가장 마지막 요소이므로 lastMatch로 tap
- 파일 가져오기 화면
tap(element: app.tabBars["DOC.browsingModeTabBar"].buttons["Recents"])
let fileView = app.collectionViews["File View"]
XCTAssertTrue(fileView.exists)
if fileView.value as? String == "Icon Mode" {
let buttons = app.navigationBars["FullDocumentManagerViewControllerNavigationBar"].buttons
tap(element: buttons.element(boundBy: buttons.count-2))
tap(element: app.collectionViews.buttons["List"])
}
let searchFields = app.searchFields.firstMatch
tap(element: searchFields)
searchFields.typeText("검색할 파일명")
app.collectionViews.element(matching: NSPredicate(format: "label CONTAINS[c] 'Search results'")).staticTexts["원하는 파일명"].tap()
- Recents 탭으로 이동
- 파일 가져오는 화면이 아이콘 모드인지 리스트 모드인지 체크해 Icon 모드면 list로 변경
- searchFeilds에 원하는 파일명 검색 후 label이 파일명인 것을 tap
그런데 이거는 다국어 적용이 안 되어서 뭔가 찝찝한 코드이긴 하다.... button tap도 Element bound -2로 접근하는것도...
ETC
- 혹시나 로컬 CI로 돌리는 경우, staticText를 영어나 한글로만 찾으면 로컬 PC의 시뮬레이터 언어 설정에 따라 테스트가 실패할 위험이 있다. 그래서 localized 클래스를 UITest에서 별도로 만들어 사용한다.
class LocalizedHelper {
func localized(_ key: String) -> String {
let uiTestBundle = Bundle(for: type(of: self))
return NSLocalizedString(key, bundle: uiTestBundle, comment: "")
}
}
Unit Test및 UITest 결과 커버리지
95%가 넘는 커버리지.. 처음봤다.
ViewModel은 UnitTest로, 시나리오 테스트는 UITest로 적용 완료!
반응형
'SwiftUI > Planting-Mind Dev Log' 카테고리의 다른 글
devlog 06. SwiftUI - FileImporter, FileExporter (0) | 2024.04.09 |
---|---|
devlog 05. Scheme '__' is not currently configured for the test action. (0) | 2024.03.21 |
devlog 04. Localization with String Catalog (0) | 2024.03.13 |
devlog 03. sink에 들어오는 값은 willSet의 값이었다. (0) | 2024.03.12 |
devlog 02. github action 세팅하기 (Feat. github action에서 xcresult 확인하는 법) (0) | 2024.03.04 |