[SwiftUI] [XCTest] SwiftUI での UITest (textfield)

SwiftUI

     
⌛️ 2 min.
別サイト(www.smalldesksoftware.com)でも、UI テストの記事が多くみられているようなので、SwiftUI でのシンプルな UI テストを説明します。

プロジェクトの設定

プロジェクトを作るときに、Include Tests のチェックを入れると、テスト用のターゲットを作ってくれます。

Project setting with test

Project setting with test
実際には、Unit Test 用と UI Test 用の2つを作ってくれます。

今回の対象は、上記のうちの UI Test です。

テスト対象プロジェクト

テキストフィールドを使ってのテストについて確認を行いたかったので、プロジェクトを作りました。

アプリ動作

テキストフィールドに入力されたテキストを、別のテキストビューに 大文字化 して表示する というアプリとしました。

identifier

テストする対象の UI 要素を取得するには、identifier を設定しておくのが確実です。

SwiftUI では、.accessibility(identifier:) を使って設定することができます。

example code


struct ContentView: View {
  @State private var text:String = "text"
  
  var body: some View {
    VStack {
      TextField("text", text: $text)
        .textFieldStyle(RoundedBorderTextFieldStyle())
        .accessibility(identifier: "textfield")
      Text(text.uppercased())
        .accessibility(identifier: "textlabel")
    }
    .padding()
  }
}

テキストを入力するフィールドの identifier は、textfield とし、
変換後のテキストを表示するラベルの identifier を textlabel としました。

Test app image

Test app image

テスト対象

テキストフィールドに入力した文字が、ただしく変換されて ラベルに表示されるかをテストする こととしました。

テストコード

テストコードは、以下です。<プロジェクト名>UITests.swift 内の1関数です。test という名称で始まっているので、テストを実行させると、この関数も実行されます。

example code


  func testExample() throws {
    // UI tests must launch the application that they test.
    let app = XCUIApplication()
    app.launch()
    
    // Use recording to get started writing UI tests.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
    let textfield = XCUIApplication().textFields.matching(identifier: "textfield").firstMatch
    let textlabel = XCUIApplication().staticTexts.matching(identifier: "textlabel").firstMatch
    textfield.tap()
    let strForClear = String(repeating: XCUIKeyboardKey.delete.rawValue, count: (textfield.value as? String)?.count ?? 0)
    textfield.typeText(strForClear)
    textfield.typeText("new text")
    
    XCTAssertEqual(textlabel.label, "NEW TEXT")
  }



Tips: テキストフィールドクリア

テキストフィールドを、tap してもクリアされません。特にクリアするための機能もないので、以下のような形で、デリートキーをタイプさせて、消去しました。

example code


let textfield = XCUIApplication().textFields.matching(identifier: "textfield").firstMatch
textfield.tap()
let strForClear = String(repeating: XCUIKeyboardKey.delete.rawValue, count: (textfield.value as? String)?.count ?? 0)
textfield.typeText(strForClear)
textfield.typeText(.....)

以前との相違

以前は、tap した後に、待つ必要があった気がするのですが、現時点(Xcode12.0.1, iOS14 シミュレータ)では、tap 直後に、typeText してもエラーとなりませんでした。

まとめ

SwiftUI を UI Test する
  • テスト時に要素を参照したい要素は、Identifier を設定する
  • UI 要素はXCUIApplication 経由で取得できる。
  • テキスト入力は、tap 後に、typeText する

1 COMMENT

とおりすがり。

SwiftUIのテストは情報が少ないので、めちゃくちゃ助かりました・・・。

返信する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です