ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
デジタルクラウン、トラックパッド、iPadポインタの自動化
Xcode 13のUIテストでデバイスを操作する方法を確認します。iPadOSのポインタ、watchOSのデジタルクラウン、強化されたmacOSのトラックパッドのスクロールAPIなど、新たに自動化された入力メソッドを紹介します。
リソース
関連ビデオ
WWDC21
-
ダウンロード
WWDCへようこそ XCTestチームのエンジニア Jeremy Goldmanです このセッションでは デバイスと Xcode 13のUIテストで デバイスとインタラクトするための 新しい方法を探求します 特に3つの新しい インタラクションに 焦点を当てます 3つの異なる プラットフォームは iPadOSポインタ watchOSDigital Crownと macOSトラックパッドです iPadOSポインタから 始めましょう
iPadOS 13.4では マウスとトラックパッドの サポートを導入 ユーザーに MagicKeyboardなどの アクセサリを使用して iPadを操作するという 新しい操作を提供 多くの開発者がこれを 最大限に活用 ポインタ固有の動作や インタラクションなど iPad Appに ホバーなどが提供 されました Xcode 13では 新しい強力な APIを提供し UIテストでiPadOS ポインタを制御します このAPIを使用すると複数の タイプのポインタの インタラクションに対して 堅牢な自動テストを作成 iPad Appで iPadOS 15以降を 実行しているデバイスで 使用できるように なります この新しいAPIをさらに 詳しく見てみましょう まずXCUIDeviceに 新しいプロパティを追加 デバイスが ポインタの インタラクションをサポート しているかチェック 次にポインタの インタラクションの実行のため XCUIElementに 新しいメソッドを追加 それはホバリングや 様々なクリックに 2本指スクロールなどです より高度なメソッド クリックアンドドラッグの ユースケースや 修飾キーを押したまま コードブロックを実行する クラスメソッドもあります これらのメソッドは精度を 強化する必要がある場合 XCUICoordinateでも 使用できます ポインタのインタラクションの ための新しいUIテストを 作成することにより新APIが iOS Appでどのように機能するか 見てみましょう このデモではサイドバーのある Fruta Appを 使用しますが 起動時は非表示と なっています ポインタ固有の機能が iPadに追加されました 2本指で水平にトラック パッドをスワイプして サイドバーを開きます UIテストを追加しましょう 空のUIテストクラスに 新しいUIテストを 追加します
このテスト内容を見て いきます Appを起動し まだ表示されていない サイドバーを アサートすることから 始めます 次に水平方向の2本指 スワイプを実行すると サイドバーが表示 されます もう1つ特筆すべき点は テスト方法に追加された 可用性属性です これは特定のiOSバージョン 以降でのみ 利用可能なメソッドの 場合に必要です ポインタインタラクション APIはiOS 15.0で 導入されました iPadシミュレータで テストを実行してみます 円のカーソル インジケータを 画面の左下隅の近くまで フォローします
これでテストのiPadでの 動作が確認されました このAppはポインタの インタラクションを サポートしていない iPhoneで動作するでしょうか このテストをiPhone シミュレータで実行してみます
テストは失敗し 次のエラー メッセージが表示 されます “このデバイスではポインタ イベントは未サポート” これを解決するには ポインタのインタラクションが サポートされているデバイス でのみ実行されるよう テストに変更を加えます この作業には XCTSkipUnlessを 使用し XCUIDeviceの新しい プロパティを設定して 未サポートのデバイスでの テストをスキップさせます iPhoneシミュレータで 再度実行します 完璧です これで未サポートのデバイスでは このテストがスキップ されるようになりました watchOSと Digital Crownなど 別デバイスと インタラクトするための 方法について 見て行くことにします Xcode 12.5では watchOS Appの UIテストサポートが 導入されました タッチイベントを合成する ためにwatchOSで 新たに利用可能になった クラウンのクリックなどの ハードウェアイベントの メソッドも含まれます Xcode 13では このサポートを 新しい方法で拡張し Digital Crownの 動作を制御します この方法では1つの パラメータ 回転数の他に Digital Crownを回転させる 速度を指定する オプションの速度 パラメータがあります この速力パラメータの タイプは XCUIGestureVelocityで プリセット値を 低速や高速にデフォルト 1秒あたりの回転数を 小数点以下まで 指定できます この新しい方法が実際に どう機能するか見てみます
現在の外気温を表示する watchOS用の 簡単な天気Appが あるとします このAppではユーザーが Digital Crownを前方に スクロールして 将来の予測気温を 確認するか 後方にスクロールして 過去の記録温度を 確認します
このクラウン回転機能が 期待どおりかどうか UIテストを 行うことにします Appの起動と 現段階では 現在の温度を表示 している予報の 時間ラベルを 表示させるテストです Digital Crownを 1回転前方に 回転させて “1時間後”と表示 その後リューズを2回転後方に 回転して ラベルが“1時間後”に 更新 されたことを確認して テストを完了します 最後にmacOSトラック パッドについて 具体的にはスクロールに 焦点を当てます スクロールは2つの カテゴリに分類できます 離散的と連続的です スクロールには正確な 増分移動があります 物理的なマウスでの スクロールホイールを 回転させてみる場合 画面上のコンテンツは 一定の増分で移動し スクロールホイールの ティックごとに 動きは非慣性 すなわち ホイールの回転を 停止させると 直ちにスクロールも 止まります 一方連続的または 段階的なスクロールは 流動的かつ動的に 動作します トラックパッドを2本指で スワイプして画像をスワイプ 画面上のコンテンツは スワイプしながらスムーズに スクロールし 動きは慣性的 すなわち 指を離した後 停止するまで 動き続けます
XCTestは現在macOSで スクロールメソッドを提供 これにより個別のピクセル 精度のスクロールを UIテストで実行可能 この方法では正確な 水平距離と垂直距離を ピクセル単位で指定 するために2つの パラメータが必要です
Xcode 13では新しい メソッドを導入 macOSでトラック パッドのようなスクロールを 実現します こうしたメソッドはオプションの 速力パラメータで スクロールする速度を 指定します 速力パラメータのタイプは XCUIGestureVelocityで 以前に説明した rotateDigitalCrown メソッドでは プリセットを使用するか 1秒あたりのピクセル数を カスタム値で 指定できます
Xcode 13は複数の プラットフォームに APIを導入して 入力メソッドを自動化 より専門的なユースケースの サポートを提供します
この新機能を使用して UIテストを作成 iPad Appでのポインタ 固有のインタラクションについては watchOSのUIテストで Digital Crownを自動化 macOSでの新しい スワイプ方法として 連続スクロールを実現 詳細については 関連セッションを ご覧いただければと 思います
引き続きWWDCを お楽しみください [音楽]
-
-
1:28 - New supportsPointerInteraction property on XCUIDevice
extension XCUIDevice { public var supportsPointerInteraction: Bool }
-
1:37 - New methods on XCUIElement and XCUICoordinate for pointer interactions on iOS
extension XCUIElement { open func hover() open func click() open func rightClick() open func doubleClick() open func scroll(byDeltaX: CGFloat, deltaY: CGFloat) open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement) open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement, withVelocity: XCUIGestureVelocity, thenHoldForDuration: TimeInterval) open class func perform(withKeyModifiers flags: XCUIElement.KeyModifiers, block: () -> Void) }
-
2:31 - Empty UI test class
import XCTest class Pointer_UI_Tests: XCTestCase { }
-
2:43 - UI test for opening the sidebar with a two-finger horizontal trackpad swipe
import XCTest class Pointer_UI_Tests: XCTestCase { @available(iOS 15.0, *) func testHorizontalScrollRevealsSidebar() throws { let app = XCUIApplication() app.launch() let sidebar = app.tables["Sidebar"] // Make sure sidebar menu is not present initially. XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially") // Swipe horizontally to reveal sidebar. app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0) // Verify sidebar is now present. XCTAssertTrue(sidebar.waitForExistence(timeout: 5), "Sidebar did not appear within 5 second timeout") } }
-
import XCTest class Pointer_UI_Tests: XCTestCase { @available(iOS 15.0, *) func testHorizontalScrollRevealsSidebar() throws { try XCTSkipUnless(XCUIDevice.shared.supportsPointerInteraction, "Device does not support pointer interaction") let app = XCUIApplication() app.launch() let sidebar = app.tables["Sidebar"] // Make sure sidebar menu is not present initially. XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially") // Swipe horizontally to reveal sidebar. app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0) // Verify sidebar is now present. XCTAssertTrue(sidebar.waitForExistence(timeout: 5), "Sidebar did not appear within 5 second timeout") } }
-
5:27 - New method on XCUIDevice for Digital Crown rotation on watchOS
// New rotateDigitalCrown API extension XCUIDevice { open func rotateDigitalCrown(delta: CGFloat, velocity: XCUIGestureVelocity = .default) }
-
6:22 - UI test to verify the app's Digital Crown rotation functionality behaves as expected
// Example use of watchOS Digital Crown API func testForecastScrolling() { let app = XCUIApplication() app.launch() let forecastTime = app.staticTexts["forecast-time"] XCTAssertEqual(forecastTime.label, "Current Temperature") // Scroll 1 full rotation forward. XCUIDevice.shared.rotateDigitalCrown(delta: 1.0) XCTAssertEqual(forecastTime.label, "One hour from now") // Scroll 2 full rotations backward. XCUIDevice.shared.rotateDigitalCrown(delta: -2.0) XCTAssertEqual(forecastTime.label, "One hour ago") }
-
7:46 - Existing API for performing discrete (mouse wheel-like) scrolling on macOS
extension XCUIElement { // Use the existing API for discrete (mouse wheel-like) scrolling. open func scroll(byDeltaX: CGFloat, deltaY: CGFloat) }
-
8:05 - New API for performing continuous (trackpad-like) scrolling on macOS
extension XCUIElement { // Use the new API for continuous (trackpad-like) scrolling. open func swipeUp(velocity: XCUIGestureVelocity = .default) open func swipeDown(velocity: XCUIGestureVelocity = .default) open func swipeLeft(velocity: XCUIGestureVelocity = .default) open func swipeRight(velocity: XCUIGestureVelocity = .default) }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。