[SwiftUI] [UnitTest] テストの作り方 ( NavigationView 編)

SwiftUI component UITest シリーズ NavigationView 編
[SwiftUI] [UnitTest] テストの作り方 ( Toggle 編) [SwiftUI] [UnitTest] テストの作り方 ( Picker 編) [SwiftUI] [UnitTest] テストの作り方 ( Image 編)

これまで、Text, Images, ValueSelectors とやってきたので、Architectural Views の1要素である NavigationView についてのテストを説明します。

NavigationView だけではなく、NavigationLink, NavigationBar 合わせて説明します。

NavigationView

NavigationView の取得

SwiftUI の NavigationView は、accessibility ID を使っての取得はできないようです。

NavigationBar

NavigationBar の取得

SwiftUI の NavigationBar は、accessibility ID を使って取得できます。

XCUIElementTypeQueryProvider の navigationBars 経由で取得できます

NavigationBar を取得

  let app = XCUIApplication()
  app.launch()

  let navigationBar = app.navigationBars["barTitle"]

NavigationBar 上のボタン

SwiftUI の NavigationBar 上のボタンは、

NavigationLink

NavigationLink の取得

SwiftUI の NavigationLink は、accessibility ID を使って取得できます。

XCUIElementTypeQueryProvider の app.buttons 経由で取得できます。

NavigationLink を取得

  let app = XCUIApplication()
  app.launch()

  let navigationBar = app.navigationBars["barTitle"]
  Let navigationLink = app.buttons["linkID"]

NavigationBar の取得

NavigationBar は、画面表示の一部ですので、設定されているタイトルを使って、取得することができます。

NavigationBar と NavigationLink を取得

  let app = XCUIApplication()
  app.launch()

  let navigationBar = app.navigationBars["barTitle"]
  Let navigationLink = app.buttons["linkID"]

NavigationBar は、.navigationTitle を使って設定されているタイトルが、その ID となります。

状態のチェック

NavigationBar

表示要素の1つなので、exists で 表示されているかどうかのチェックができます。

また、設定されているタイトルが、accessibility ID なので、要素が取得できたかどうかで、期待するタイトルが設定されているかをテストすることができます。

NavigationLink

表示要素の1つなので、exists で 表示されているかどうかのチェックができます。

表示文字列は、label をチェックすることでテストできます。

操作

NavigationBar

NavigationBar 自体への操作ではありませんが、Back ボタンを押すには、以下のようにします。

NavigationBar で Back ボタン操作

  let backButton = childViewBar.buttons.firstMatch
  backButton.tap()

NavigationLink

Button と同等の扱いなので、tap() することで、クリック操作を行えます。

テストコード

以下では、RootViewTitle という Title をつけた、NavigationView が表示されていることをテストし、NavLink という accessibility ID をつけた NavigationLink も表示されていることをテストしています。

NavigationView/NavigationLink テスト

  // UI tests must launch the application that they test.
  let app = XCUIApplication()
  app.launch()

  //(1)
  let rootViewBar = app.navigationBars["RootViewTitle"]
  XCTAssertTrue(rootViewBar.exists)

  //(2) 
  let linkToChild = app.buttons["NavLink"]
  XCTAssertTrue(linkToChild.exists)
コード解説
  1. RootViewTitle という NavigationBar を取得し、表示されていることを確認
  2. NavLink という accessibility ID が設定されたボタン(NavigationLink)を取得し、表示されていることを確認

アプリとテストコード例

起動すると NavigationView が表示され、画面中央のリンクをクリックすると ChildView に遷移し、Back ボタンで、最初のビューに戻るアプリと、そのアプリ用のテストコードです。

NavigationView アプリ

「NavigationView アプリ」
NavigationView アプリ

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/06
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink("to Child View", destination: ChildView())
                .navigationTitle("RootViewTitle")
                .accessibility(identifier: "NavLink")
        }
        .padding()
    }
}

struct ChildView: View {
    var body: some View {
        Text("Child View")
            .padding()
            .accessibility(identifier: "NavChildText")
            .navigationTitle("ChildViewTitle")
    }
}
Image アプリ テストコード

    func testNavView() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()
        
        let rootViewBar = app.navigationBars["RootViewTitle"]
        XCTAssertTrue(rootViewBar.exists)
        
        let linkToChild = app.buttons["NavLink"]
        XCTAssertTrue(linkToChild.exists)
        linkToChild.tap()

        let childViewBar = app.navigationBars["ChildViewTitle"]
        XCTAssertTrue(childViewBar.exists)
        
        let backButton = childViewBar.buttons.firstMatch
        backButton.tap()
        
        XCTAssertTrue(rootViewBar.exists)
    }

まとめ:SwiftUI の NavigationView/NavigationLink をテストする

SwiftUI の NavigationView/NavigationLink をテストする
  • XCUIApplication から、.navigationTitle で指定したタイトルを ID として指定することで、NavigationBar を取得する
  • XCUIApplication から、accessibility ID 指定で NavigationLink を Button として取得する
  • NavigationLink のクリックは、tap()
  • NavigationBar の Back ボタンは、buttons.firstMatch で取得

説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

コメントを残す

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