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

SwiftUI component UITest シリーズ Picker 編

Picker

対象要素の取得

SwiftUI の Picker は、UITest 視点での部品としては、 Picker と Wheel に分けられます。

Picker には、ラベルの情報が保持していて、選択情報は、Wheel 側が保持しています。

ところが、この Wheel に accessibility ID を付与できません。
Accessibility ID を付与しても、期待する要素を取得することができません。

Picker には、Accessibility ID を付与できます。そして、Picker に対して、Wheel は1つであることを考えると、以下のようなコードで、該当 Wheel を取得することができます。

example code

let picker = app.pickers["PickerID"]
let wheel = picker.pickerWheels.firstMatch

状態のチェック

Wheel の状態をチェックすることで、(SwiftUI での) Picker で選択された状態をチェックできます。

value プロパティに、String で 保持されています。

ただし、.tag で設定されたものではなく、ラベルとして使用されている String です。

Wheel での選択を取得

let app = XCUIApplication()
app.launch()

let picker = app.pickers["OptionPicker"]
let wheel = picker.pickerWheels.firstMatch
    
let selectedValue = wheel.value as? String ?? "no value"

値の設定

以下のメソッドを使うことで、該当位置まで移動でます。

Picker 該当位置まで移動 method

func adjust(toPickerWheelValue pickerWheelValue: String)

Apple のドキュメントは、こちら

Wheel での選択

let app = XCUIApplication()
app.launch()

let picker = app.pickers["OptionPicker"]
let wheel = picker.pickerWheels.firstMatch

wheel.adjust(toPickerWheelValue: "Value2")
    
let selectedValue = wheel.value as? String ?? "no value"

テストコード例

以下は、Picker で "Value3" という選択肢を選択して、その後、Wheel がその値を持っているかを確認しています。

Picker テスト例

  let app = XCUIApplication()
  app.launch()

  // (1)
  let picker = app.pickers["OptionPicker"]
  let wheel = picker.pickerWheels.firstMatch
  XCTAssertTrue(wheel.exists)

  // (2)
  wheel.adjust(toPickerWheelValue: "Value3")

  // (3)
  XCTAssertEqual(wheel.value as! String, "Value3")
コード解説
  1. Picker を取得 (Wheel を取得する必要があることに注意)
  2. "Value3" という行を選択
  3. 選択操作後に、Wheel の値をテスト



アプリと、テストコード例

画面に、Picker と Picker での選択に連動してアップデートされる Text が表示されるアプリです。

Picker テストアプリ

「Picker テストアプリ」

Picker テストアプリ

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/10/29
//  © 2020  SmallDeskSoftware
//

import SwiftUI

public enum Options: String, Identifiable, CaseIterable {
  case option1 = "OptionValue1"
  case option2 = "OptionValue2"
  case option3 = "OptionValue3"
  public var id: String { self.rawValue }
}

struct ContentView: View {
  @State private var selectedOption: Options = .option1
  
  var body: some View {
    VStack {
      Picker("Select option", selection: $selectedOption) {
        Text("Value1")
          .tag(Options.option1)
        Text("Value2")
          .tag(Options.option2)
        Text("Value3")
          .tag(Options.option3)
      }
      .accessibility(identifier: "OptionPicker")
      .padding()

      Text("selected option value is \(selectedOption.rawValue)")
        .accessibility(identifier: "SelectedOption")
        .padding()
    }
    .padding()
  }
}
Picker アプリ テストコード

  func testPicker() throws {
    // UI tests must launch the application that they test.
    let app = XCUIApplication()
    app.launch()
    
    let picker = app.pickers["OptionPicker"]
    XCTAssertTrue(picker.exists)
    let wheel = picker.pickerWheels.firstMatch
    XCTAssertTrue(wheel.exists)

    let label = app.staticTexts["SelectedOption"]
    XCTAssertTrue(label.exists)

    wheel.adjust(toPickerWheelValue: "Value3")
    XCTAssertEqual(wheel.value as! String, "Value3")
    
    XCTAssertEqual(label.label, "selected option value is OptionValue3")
  }

まとめ:SwiftUI の Picker をテストする

SwiftUI の Toggle をテストする
  • XCUIApplication から、accessibility ID 指定で Picker を取得し、そこから、Wheel を取得する
  • func adjust(toPickerWheelValue pickerWheelValue: String) を使って、指定行を選択する
  • Picker の選択値は、value プロパティから String として取得できる
  • SwiftUI では、accessibility ID は、.accessibility modifier で付与する

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

コメントを残す

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