ハイライト
Xcode 13 では、iPadOS ポインター、watchOS Digital Crown、macOS トラックパッド スクロール自動化 API が XCTest UI テストに追加され、開発者は以前は実際の入力デバイスに依存していたインタラクション パスを検証できるようになります。
主要内容
iPad アプリがマウスとトラックパッドをサポートした後、多くのインタラクションはポインター環境でのみ発生します。たとえば、ユーザーがボタンの上にカーソルを置くとアニメーションが表示され、2 本の指でトラックパッドを水平にスワイプするとサイドバーが開きます。以前は、この種の動作を UI テストに組み込むのは困難でした。テストはタッチ パスのみをカバーでき、ポインタ パスは手動でクリックする必要がありました。
Xcode 13 は、iPadOS ポインターを XCTest が駆動できる入力ソースに変換します。テスト コードでは、ホバー、クリック、右クリック、ダブルクリック、2 本指スクロール、修飾キーを押したまま、クリック アンド ドラッグを実行できます。テストの目標は、「ページを開くことができる」から「Magic Keyboard を使用したときにページが期待どおりに応答する」まで進められます。
この機能には実際上問題があります。同じアプリが iPad と iPhone の両方で実行される可能性があるということです。 iPhone はポインタ操作をサポートしていません。ポインター テストを直接実行すると、テストは失敗します。 Xcode13も利用可能supportsPointerInteraction、環境制限を製品の欠陥として誤って報告することを避けるために、サポートされていないデバイスではテストをスキップできます。
watchOS にも同様の問題点があります。多くの時計アプリケーションは、時間のスクロール、値の調整、リストの参照など、中心的な入力方法として Digital Crown を使用します。 Xcode 12.5 はすでに watchOS UI テストとクラウン クリックをサポートしており、Xcode 13 ではクラウンの回転が追加されています。テストでは回転数と速度を指定して、インターフェースのテキストがそれに応じて変化するかどうかを検証できます。
macOS の問題は山積しています。マウス ホイールは個別スクロール、トラックパッドは連続スクロールです。以前、XCTest は macOS 上でピクセル単位のスクロール方法をすでに備えており、これはマウス ホイールのシミュレートに適していました。 Xcode 13 は新しいタッチパッドのような継続性を追加しますswipe慣性と速度による回転挙動をテストするために使用される方法。
詳細
iPadOS ポインタサポートの検出
(01:28) Xcode 13 でXCUIDevice参加してくださいsupportsPointerInteraction。現在のデバイスがポインター操作をサポートしているかどうかをテストに伝えます。
extension XCUIDevice {
public var supportsPointerInteraction: Bool
}
キーポイント:
XCUIDevice現在の UI テストが実行されているデバイスを表します。supportsPointerInteractionブール値を返します。- iPad ポインター テストでは、実行するかスキップするかを決定する前に、この値をチェックできます。
(04:36) 完全なテストで、Apple は以下を使用しました。XCTSkipUnlessポインターの操作をサポートしていないデバイスをスキップします。
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")
}
}
キーポイント:
@available(iOS 15.0, *)iOS 15 以降で利用可能な API のみを使用するようにこのテストをマークします。XCTSkipUnless条件が満たされない場合はテストをスキップします。XCUIDevice.shared.supportsPointerInteractionポインター操作をサポートしていないデバイスをフィルターで除外します。XCUIApplication()テスト対象のアプリケーション オブジェクトを作成します。app.launch()テスト対象のアプリケーションを起動します。app.tables["Sidebar"]アクセシビリティのロゴまたは名前が見つかりましたSidebar形状。XCTAssertFalse(sidebar.exists, ...)起動時にサイドバーが存在しないことを確認します。app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0)指定されたテキスト要素に対して 2 本の指で水平スクロールを実行します。waitForExistence(timeout: 5)検証サイドバーが表示されるまで最大 5 秒待ちます。
iPadOS ポインタ操作方法
(01:37) Xcode 13 でXCUIElementそれにポインター メソッドのセットを追加します。講演では、これらの手法は次のような場合にも使用できることにも言及しました。XCUICoordinate、より正確な座標が必要な場合は、座標オブジェクトを使用できます。
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)
}
キーポイント:
hover()要素の上にポインタを移動して、ホバー アニメーションまたはホバー状態をテストします。click()通常のクリックを実行します。rightClick()右クリックを実行します。doubleClick()ダブルクリックを実行します。scroll(byDeltaX:deltaY:)2本指でスクロールを実行し、deltaX水平距離をコントロールし、deltaY垂直距離をコントロールします。click(forDuration:thenDragToElement:)まず長押ししてから、別の要素までドラッグします。- 持ってくる
withVelocityそしてthenHoldForDurationオーバーロードでは、ドラッグ速度とドラッグ終了後の滞留時間を指定できます。 perform(withKeyModifiers:block:)修飾キーを押したままにして、コード ブロック内で操作を実行します。
watchOS デジタル クラウンの回転
(05:27) Xcode 13 でXCUIDevice参加してくださいrotateDigitalCrown。回転数を受け取り、速度を指定できます。
// New rotateDigitalCrown API
extension XCUIDevice {
open func rotateDigitalCrown(delta: CGFloat, velocity: XCUIGestureVelocity = .default)
}
キーポイント:
rotateDigitalCrown(delta:velocity:)Digital Crown 回転イベントを合成します。delta回転数を表します。- 正の数は正転を意味し、負の数は逆回転を意味します。
velocity種類はXCUIGestureVelocity。- スピードを利用できる
.slow、.fast、.defaultプリセットまたはカスタムの 10 進数値を使用できます。単位は 1 秒あたりの回転数です。
(06:22) このスピーチでは、天気予報アプリを使用してテスト方法を説明しています。リューズを前方にスクロールすると将来の温度が表示され、後方にスクロールすると過去の温度が表示されます。
// 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")
}
キーポイント:
XCUIApplication()テスト対象の watchOS アプリケーション オブジェクトを作成します。app.launch()アプリケーションを起動します。app.staticTexts["forecast-time"]予測時間を示すテキストを見つけます。- 初め
XCTAssertEqual初期状態が現在の温度であることを確認します。 rotateDigitalCrown(delta: 1.0)前方に一周回転させます。- 2番目
XCTAssertEqual検証インターフェースは 1 時間後に更新されます。 rotateDigitalCrown(delta: -2.0)後方に完全に 2 回転します。- 最後のもの
XCTAssertEqual検証インターフェースは 1 時間前に更新されました。
macOS の個別スクロールと連続スクロール
(07:46) macOS のオリジナルscroll(byDeltaX:deltaY:)個別のスクロールに適しています。スピーチでは、これをマウス ホイールに例えました。各フレームは一定の距離を移動し、入力が停止されるとコンテンツはすぐに停止します。
extension XCUIElement {
// Use the existing API for discrete (mouse wheel-like) scrolling.
open func scroll(byDeltaX: CGFloat, deltaY: CGFloat)
}
キーポイント:
scroll(byDeltaX:deltaY:)既存の API があります。deltaX水平スクロール距離を指定します。deltaY垂直スクロール距離を指定します。- この方法は、ピクセルレベルの非慣性スクロールテストに使用されます。
(08:05) Xcode 13 では、トラックパッド上での 2 本の指のスライドをシミュレートするのに適した、新しい連続スクロール メソッドが追加されています。連続スクロールには速度と慣性があり、指が離れるとコンテンツは徐々に停止します。
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)
}
キーポイント:
swipeUp(velocity:)合成は上にスライドします。swipeDown(velocity:)合成は滑り落ちます。swipeLeft(velocity:)構成スライド左。swipeRight(velocity:)構成を右にスワイプします。velocity種類はXCUIGestureVelocity。- 速度にはプリセット値またはカスタムの 10 進値を使用できます。単位はピクセル/秒です。
重要ポイント
-
やるべきこと: iPad のサイドバー、列ナビゲーション、およびキャンバス アプリケーションのポインター テストを作成します。 実行する価値がある理由: Xcode 13 では、UI テストで 2 本指のスクロール、ホバリング、クリックを実行できるため、ポインター固有のパスを手動で受け入れる必要がなくなりました。 開始方法: UI テストで使用されます
XCTSkipUnless(XCUIDevice.shared.supportsPointerInteraction, ...)テストを保護し、ターゲット要素で呼び出します。scroll(byDeltaX:deltaY:)またはhover()。 -
やるべきこと: iPad の右クリック メニューの回帰テストを作成します。 価値がある理由: ポインター API のサポート
rightClick()、コンテキスト メニューが表示されるかどうか、およびメニュー項目がクリック可能かどうかをオーバーライドできます。 開始方法: トリガーメニューを見つけますXCUIElement、 電話rightClick()、メニュー内のボタンまたはテキストが存在することをアサートします。 -
やるべきこと: watchOS クラウン調整インターフェイスの境界テストを作成します。 実行する価値がある理由:
rotateDigitalCrown(delta:velocity:)回転方向や回転数を指定できるため、タイムライン、ボリューム、温度、タイマーなどのクラウン駆動のインターフェースのテストに適しています。 開始方法: watchOS UI テストでアプリを起動し、現在のラベルを読み取り、呼び出しますXCUIDevice.shared.rotateDigitalCrown(delta:)をクリックして、ラベルまたは値の変更を確認します。 -
やるべきこと: タッチパッドのスクロール テストを macOS の長いリストまたはタイムラインに追加します。 実行する価値がある理由: 新しい
swipeUp、swipeDown、swipeLeft、swipeRightトラックパッド入力に近くなり、慣性スクロール時の読み込みと選択の動作がオーバーライドされます。 開始方法: スクロール コンテナ要素を選択して呼び出しますswipeUp(velocity:)またはswipeDown(velocity:), 対象のコンテンツが表示されるか確認してください。 -
やるべきこと: 修飾キーを使用してポインター操作をテストします。 実行する価値がある理由:
perform(withKeyModifiers:block:)修飾キーを押したままにすると、ファイル選択、範囲選択、キャンバス エディターに適した UI テストでクリックまたはドラッグを実行できます。 開始方法:click()またはドラッグアンドドロップでXCUIElement.perform(withKeyModifiers:block:)クロージャで、選択された状態の変更をアサートします。
関連セッション
- XCTest で予想される失敗を受け入れる — トーク
XCTExpectFailure、このフィールドを操作して UI テストの失敗シグナルを改善するのに適しています。 - テストを繰り返して信頼性の低いコードを診断する — ポインタの位置決め、スクロール、クラウンのテストで時折失敗する場合に適した、繰り返しのテスト実行について説明します。
- メモリの問題の検出と診断 — 同じテスト ツール機能セットに属する Xcode メモリ診断と XCTest コレクションについて説明します。
- 究極のアプリケーション パフォーマンス サバイバル ガイド - UI 自動化を超えて品質チェックを拡張するのに適したパフォーマンス メトリクス、MetricKit と XCTest について説明します。
コメント
GitHub Issues · utterances