XCUITestでUIテストを自動化する
本章では、iOSでXCUITestを用いた、UIテストの作成方法について共有します。
XCUITestとは
XCUITestは、XCodeに付属したUI上でテストを実行できるテストフレームワークです。
XCUITestでは、アプリのUI要素に対して、タップ、スワイプ、スクロールといったユーザーの操作を伴った動作確認ができます。
XCUITestにより、UIテストの自動化ができ、特に回帰テスト中に時間を節約できます。
AndroidのEspresso同様、XCode上の操作記録ツールを利用することで、コードの作成なくテストケースの作成もできます。
XCUITestによるUIテストの作成
事前準備
まずは、テスト開始前に常に初期設定となるよう、アプリを削除する処理を準備しておきます。用意の仕方については、以下のサイトを参照しました。 qiita.com
[Springboard.swift]
// // Springboard.swift // import XCTest import Foundation class Springboard: XCTestCase { static let shared = Springboard() let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") /** Terminate and delete the app via springboard */ func deleteApp() { XCUIApplication().terminate() // Force delete the app from the springboard let icon = springboard.icons["【アプリ名】"] if icon.exists { let iconFrame = icon.frame let springboardFrame = springboard.frame icon.press(forDuration: 1.3) // Tap the little "X" button at approximately where it is. The X is not exposed directly springboard.coordinate(withNormalizedOffset: CGVector(dx: (iconFrame.minX + 3) / springboardFrame.maxX, dy: (iconFrame.minY + 3) / springboardFrame.maxY)).tap() // Wait for showing alert let alert = springboard.alerts["Delete “【アプリ名】”?"] let alertExists = NSPredicate(format: "exists == true") expectation(for: alertExists, evaluatedWith: alert, handler: nil) waitForExpectations(timeout: 5, handler: nil) springboard.alerts.buttons["Delete"].tap() XCUIDevice.shared.press(.home) } } }
テストで使用する便利関数
XCUITestでも、ユーザー操作による画面上のレスポンスを待機する必要があります。 そこで、ユーザー操作を待ち合わせる、拡張関数を事前に定義しておきます。 [Extension.swift]
// // Extension.swift // import XCTest import Foundation extension XCUIElement { func tapIfExists(timeout: Double = 10) { if self.waitForExistence(timeout: timeout) { self.tap() } } func lazyTap(time: uint = 1){ sleep(time) self.tap() } func type(text: String) { self.tap() self.typeText(text) } }
テストコード本体
それでは、テストファイルを記述していきます。 自前で用意した拡張関数を利用して、画面操作後の待機を行いテストを進行させます。システム通知への操作は、「springboard」を利用してUIテストを継続していきます。 [hogehogeUITests.swift]
// // hogehogeUITests.swift // import XCTest import Foundation class hogehogeUITests: XCTestCase { private let app = XCUIApplication() override func setUp() { // Put setup code here. This method is called before the invocation of each test method in the class. super.setUp() // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false // Delete the old application. Springboard().deleteApp() // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. app.launch() } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() app.terminate() } func test_foo() { // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. // Click after finding elements which contains texts "ほげほげ". app.buttons["ほげほげ"].tap() // Enter texts"ふが" in an element which contains texts "ぴよ". // Allow notifications form system. XCUIApplication(bundleIdentifier: "com.apple.springboard").buttons["Allow"].tapIfExists() } }
筆休め
Swiftでもリグレッションテスト向けの自動化されたITテスト用意しておくことで、コストが低く効果が高いテストを行えます。 アプリの品質が、事業の成否となる場面もあるので、しっかりとしたテストを行っておきたいですね。
以上、「XCUITestでUIテストを自動化する」でした。