SwiftUIのIntegrationTestを行いたい場合、新しいフレームワークである都合から実機を用いたテストを行うのが良いです。
(Preview・シミュレーターだと実機で発生するような不具合に気がつくことが出来ない、そして、そういったケースがやたらと多い…)
このテストを自動化したい場合、利用出来るテストツールにはAppiumが挙げられるかと思います。
SwiftUIでTabViewを利用する場合、各TabBarItem(TabBarButton)にAccessibilityIdentifierを設定する方法が提供されおらず、Appium側からTabの切り替え操作を行うことができません。
(Appiumではユニークな要素取得のためにAccessibilityIdentifierを参照します)
UITabBarControllerにアクセスする
SwiftUIではUIKitの要素に触ることは出来ませんので、SwiftUI-Introspectというライブラリを利用します。
これを利用することで、以下のようにUITabBarControllerへの参照を取得出来るようになります。
import SwiftUI
import Introspect
struct ContentView: View {
var body: some View {
TabView {
Text("Tab1").tabItem {
Label("tab1", systemImage: "circle")
}
Text("Tab2").tabItem {
Label("tab2", systemImage: "square")
}
}
.introspectTabBarController { tabBarController in
print(tabBarController)
}
}
}
UITabBarButtonにAccessibilityIdentifierを設定する
TabViewにあるボタンはUITabBarButtonというViewです。
(TabBarItemではありません!)
UITabBarButtonはUIKitでは公開されていないViewなのでこの型名を指定してUITabBarButtonを取得することは出来ないのですが、
幸いにもUIControlを継承しているViewなのでキャストを通して参照を取得することが出来ます。
let tabButtons = tabBarController.tabBar.subviews.compactMap { $0 as? UIControl }
取得したUIControlの参照は左から並ぶTabBarButtonとなるので、配列のIndexを見ながら各ボタンに適当なIdentifierを設定していけばOKです。
tabButtons.enumerated().forEach { (index, tabButton) in
switch index {
case 0:
tabButton.accessibilityIdentifier = "tab1"
case 1:
tabButton.accessibilityIdentifier = "tab2"
default:
break
}
}
将来的に言語・フレームワークのアップデートで動作しなくなる可能性がある方法です。
将来的にはこのような方法を採用しなくても、AccessibilityIdentifierを設定するより良い方法が提供されるようになることを期待したいですね。