View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

WWDC25に戻る

  • 概要
  • トランスクリプト
  • コード
  • 記録、再生、レビュー:Xcodeを使用したUI自動化

    Xcodeで、XCUIAutomationテストの記録、実行、保守を行う方法を学びましょう。テストプランの構成を使用して、多数のロケール、デバイスタイプ、システム環境でXCTest UIテストを再生する方法や、Xcodeのテストレポートでテスト結果をレビューし、実行時のスクリーンショットやビデオをダウンロードする方法を確認します。また、アクセシビリティの導入と安定した高品質な自動化コードの記述を通じて、自動化に向けたアプリの準備を行うためのベストプラクティスについても説明します。

    関連する章

    • 0:00 - イントロダクションとアジェンダ
    • 3:58 - UI自動化の概要
    • 6:26 - 自動化に向けたアプリの準備
    • 11:32 - インタラクションの記録
    • 17:30 - 複数の構成での再生
    • 20:54 - ビデオと結果のレビュー
    • 24:16 - 次のステップ

    リソース

    • Delivering an exceptional accessibility experience
    • Improving code assessment by organizing tests into test plans
    • Performing accessibility testing for your app
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC24

    • Swift Testingについて

    WWDC23

    • アプリのアクセシビリティ監査の実施
    • SwiftUIとUIKitを使ったアクセシブルなアプリの作成
    • Xcode のテストレポートで素早く失敗を修正
    • Xcode Cloudでの実用的ワークフロー作成

    WWDC22

    • Xcode Cloud用の高速で信頼性の高いテストを作成する

    WWDC21

    • SwiftUIのアクセシビリティ: 基礎を超えて
  • このビデオを検索

    こんにちは Maxです Xcodeチームのエンジニアです Xcodeには非常に多くの 素晴らしい機能と体験があります 圧倒されるほどです 例えば 様々なデバイス 言語 構成におけるアプリの実行状況を ワンクリックで確認できる ことをご存知でしたか さらに アプリの実行ごとに 優れた品質の ビデオを録画することもできます これらはすべて XcodeのUI自動化の パワーを活用して実現できます その仕組みを見てみましょう 最初にUI自動化の概要について説明します 次に アプリを準備して 操作を自動化コードとして記録し 複数のデバイスや言語で自動化を再生します そして最後に 結果のビデオ録画を見て 各実行が成功したか失敗したかに 関するレポートを確認します

    まず UI自動化の仕組みの概要を説明します

    Xcodeには Swift TestingとXCTestの 2つのテストフレームワークがあります どちらのフレームワークでも 様々な構成でアプリと ソースコードをすばやくテストできます

    XCTestをインポートすると XCUIAutomationというフレームワークが 自動的に組み込まれます XCUIAutomationを使用すると アプリを自動化でき 人間が行うようにアプリを操作できます これらのフレームワークが連携することで 包括的なアプリテストスイートが実現します 個人的には 非常に素晴らしいことだと思います 包括的なアプリテストスイートは通常 単体テストとUI自動化テストの 両方で構成されます 単体テストでは アプリのロジックと モデルをテストし Swiftテストによって ユーザーインターフェイスを持たない フレームワークやSwiftパッケージ上で テストを実施できます 一方 UI自動化テストでは アプリのユーザー体験や Appleハードウェアとの統合 一般的なワークフローの動作を検証します

    一般に テストスイートでは UIテストよりも単体テストの割合が多く デベロッパはコード全体を カバーすることを目指します しかし UI自動化テストでは アプリの外観や動作 オペレーティングシステムの 他の部分との統合を確認できます これを実施することには 非常に多くのメリットがあります

    例えば タップ スワイプなどの ジェスチャーやクリックにより 人間と同じようにアプリをテストできます VoiceOver Voice Control ダイナミックタイプなどの 支援技術を使用する人々が アプリをどのように受け止めるかを 理解することができます

    アプリがサポートする すべての言語や地域での アプリの実行状態を確認でき 長い文字列を使用する言語や 右から左に書く言語など アプリの外観に大きく影響する言語に 焦点を当てることができます アプリとAppleハードウェアの機能との統合 つまり アクションボタン カメラボタン Apple TV Remote Apple WatchのDigital Crownなどの 機能との統合をテストできます 最後に アプリの起動性能をテストできます これは アプリをどれだけすばやく 使い始めることができるかを理解するための 重要な指標です UI自動化のワークフローを設定する 3つの重要なフェーズとして 記録 再生 レビューがあります

    まず タップやスワイプ ハードウェア ボタンの押下などの操作を記録します すると Xcodeが自動的にそれらを コードとして記述します 次に デバイス上とXcode Cloud内の 両方について 複数のデバイス 言語 地域 デバイスの向きで インタラクションを再生します 最後に それらすべての構成で アプリの実行の ビデオと結果を参照して どれが成功し どれが失敗したかを 確認します UI自動化は すべてのAppleプラットフォーム iOS iPadOS macOS watchOS tvOS visionOS(iPad向け)でサポートされ 同じ自動化を複数のプラットフォームで 実行することもできます したがって 一度自動化を構築したら すべてのサポート対象デバイスで 実行できます つまり ワンクリックでコードを変更する 必要なく Mac iPhone Vision Proで アプリの実行を確認できます UI自動化の仕組みを簡単に説明します UI自動化は ジェスチャーや ハードウェアイベントを使用して 人間と同じようにアプリを操作します 自動化はアプリから完全に 独立して実行されるため アプリのモデルやデータに直接 アクセスすることはできません

    UI自動化は 実行するジェスチャーを オペレーティングシステムに伝え 同期的に待機して 一度に1つずつ ジェスチャーを完了させます

    これらのアクションには アプリの起動 ボタンやナビゲーションの操作 ダークモードなどの システム状態の設定が含まれ 必要に応じて デバイスに対して 場所をシミュレートすることもできます アクセシビリティはAppleの 基本的な価値の1つです Appleの支援技術は 身体的 視覚的 聴覚的 運動的な障がいの有無に関係なく 誰もがアプリを使えるようにサポートします Appleは これらの技術のほとんどが デベロッパによる作業の必要なく アプリにおいて デフォルトで機能するように 懸命に取り組んでいます とはいえ サポートを追加することで アプリの体験が豊かになり より簡単に自動化できます 重要なことは アクセシビリティが UI自動化の基盤となる フレームワークであることです アクセシビリティ体験が優れていれば UI自動化体験も優れたものになります アクセシビリティは 要素の種類 ラベル 値 フレームなどの情報を UI自動化に直接提供しますが アクセシビリティで把握できるものが 人間が把握できるものと1対1で 対応している必要はありません 例を見てみましょう この画面では ボタンがUIに表示されていますが アクセシビリティは それ以上の 情報を把握します アクセシビリティは要素の種類と ラベルを把握して それらをUI自動化に公開し さらに identifierプロパティも公開します アクセシビリティの識別子を使用すると 画面上の任意の要素を その周囲にある すべての要素との関係で一意に記述できます 識別子はローカライズの対象ではないので どの言語またはデバイスでも 識別子を 使用して同じUI要素を参照できます

    チェックボックスなどの ステートフル要素の場合 valueプロパティを使用できます これにより アクセシビリティとUI自動化の 両方で要素の現在の状態を把握できます

    アクセシビリティの詳細については WWDC23の「Build accessible apps with SwiftUI and UIKit」や WWDC21の「SwiftUI Accessibility: Beyond the basics」をご確認ください

    UI自動化とアクセシビリティの 連携について説明したので アプリの自動化を準備しましょう

    最初にアクセシビリティ識別子を追加します 次に アプリのアクセシビリティ について簡単に確認し 最後に 新しいUIテストターゲットを追加し インタラクションをコードとして 記録する準備を整えます その前に アプリはUI自動化とUIの記録を すでにサポートしていて デベロッパによる作業の必要なく すぐに使用できることを指摘しておきます これから説明する手順の実施は 必須ではありませんが 実施することで より適切で より質の高い 結果につながる可能性があります アクセシビリティ識別子の追加は SwiftUI UIKit AppKitで記述された ビューコードで行うことができます アクセシビリティ識別子は 自動化するアプリ内の任意の要素を 一意に識別する最善の方法です アクセシビリティ識別子は ローカライズ対象の文字列または 動的なコンテンツを含む要素に 追加することをお勧めします これには 任意のデータモデル内で 取得されるコンテンツや インターネットからダウンロードされる コンテンツが含まれます

    適切な識別子は アプリ全体で一意であり それらが設定されている要素の 詳細を適切に記述し 静的でありコンテンツの変化に 影響されないものです

    タイトルや説明は変化する場合が ありますが 適切な識別子は それが付与されている要素の コンテンツを常に記述します これにより 私の素敵なランドマークを 永遠に残すことができます

    SwiftUIでは accessibilityIdentifier 修飾子を任意のUI要素に 追加できます これは ビューやその親ビューが アクセシビリティから把握できる 状態にある限り認識されます

    特にアプリで何度も使用されるビューの場合 識別子をビューのインスタンスに固有な ものにすることをお勧めします この例では ランドマークの idプロパティを使用して 各インスタンスに対して 識別子を一意にしています

    UIKitでは アクセシビリティ要素である 任意のUIViewに対して accessibilityIdentifierプロパティを 設定できます コントロール テキスト 画像などの ほとんどのUIビューは デフォルトでアクセシビリティ要素であり 通常 特別な作業は不要です

    accessibilityLabelや accessibilityTraits accessibilityValueなどのプロパティは VoiceOverなどの支援技術に利用でき UI自動化でも利用できます

    ただし accessibilityIdentifier プロパティは VoiceOverで読み上げることができず また アプリを使用するユーザーに 公開されることもありません そのため 表のセルのインデックスや 画像のシンボル名など 自動化にのみ役立つ情報を 提供するのに便利です Xcodeのコーディングアシスタントを使って アクセシビリティ識別子を 追加することもできます 例えば アクセシビリティ識別子を このビューの適切な部分に 追加するように指示すると このようになります コーディングアシスタントはランドマークの idプロパティの使い方さえ知っていて 各識別子を完全に一意にしてくれます とても便利ですね UIの記録を開始する前にアプリ全体での アクセシビリティの動作を 確認することをお勧めします これは歯医者に行く前にデンタルフロスで 歯をきれいにするようなものです どれだけうまくやっているかを すぐに知ることになります これにより有用な情報を 得ることができます Xcodeには Accessibility Inspector というアプリが付属しており これを使って アクセシビリティの問題を 検出 診断 修正できます このアプリはXcodeトップレベルメニューの 「Open Developer Tool」から 起動できます Spotlightから起動することもできます

    Accessibility Inspectorでは 任意のプラットフォーム上でアプリ内の 任意のビューに関するアクセシビリティ値を 一覧表示できます 確認するプラットフォームを選択してから 要素インスペクタをクリックし そのプラットフォーム上で 確認したいUI要素を操作します 要素プロパティの一覧が表示されます セクションにあるプロパティなど いくつかのプロパティは UI自動化に非常に役立ちます ビューに情報が欠けている場合は アプリのソースコードを変更して 追加するとよいでしょう 各プロパティの詳細を確認するには プロパティ名をクリックします ポップオーバーには 設定されるプロパティが表示され 関連する情報も提供されます

    アクセシビリティ機能の詳細については サンプルコードプロジェクトの 「Delivering an exceptional accessibility experience」をご覧ください このプロジェクトでは 様々なアクセシビリティ機能を使用し UIの自動化に適しているアプリの 優れたサンプルコードを提供しています また 「Performing accessibility testing for your app」の記事を確認し 様々な支援技術を使って アプリのアクセシビリティを 確認する方法について理解を深めてください 自動化を開始する準備ができたら 新しいUIテストターゲットを追加して 自動化コードを配置する場所を 設定する必要があります

    Xcodeのプロジェクト設定ビューで ターゲットリストの下にあるボタンを 使用して新しいターゲットを追加します

    次に ポップオーバーから を選択します

    をクリックすると 新しい UIテストフォルダとテンプレートが プロジェクトに追加されます テンプレートには 作業を開始するのに 役立つ簡単なテストがいくつかあります これで インタラクションをSwiftコード として記録する準備が整いました このためにiOSシミュレータと Xcodeを使用しましょう 数年前 私の母と妹は 私を置いてオーストラリアへの 1か月の旅行に出かけました 一緒に行くことができず 私は大変がっかりしました 幸い 私にはそのためのアプリがあります 今年のWWDCの Landmarksサンプルプロジェクトを使用して 私自身の休暇を計画してみます 旅行を計画するインタラクションを いくつか記録するので アプリの今後のバージョンで ワークフローが中断するのを 避けることができます UIテストのソースファイルを 初めて開いたとき ポップオーバーが表示され UIの記録を開始する方法が示されます 次に サイドバーのボタンを使用して UIの記録を開始します Xcodeがアプリを自動的にビルドし シミュレータでアプリを再起動します

    アプリが起動したので ビューに進みます

    アプリを操作すると インタラクションを表すコードが ソースエディタに記録されます ボタンをタップして 新しいコレクションを追加し オーストラリアへの私自身の 旅行を計画し始めます 次に ボタンをタップして 旅行の名前を変更します 旅行の名前を「Max’s Australian Adventure」に変更します

    入力に合わせて Xcodeは私のテストを 最新の状態に保ちます

    ランドマークのコレクションを編集します

    グレートバリアリーフやウルルなどの オーストラリアのランドマークを追加して チェックマークをタップするだけです

    ビューに戻ると オーストラリアのランドマークを 含むコレクションが 追加されたことを確認できます

    UIの記録を停止するには Xcodeのボタンを押します 記録を終了したら 想定した 自動化が得られたことを 確認するために いくつかの 作業を行う必要があります まず 記録されたコードを確認します 次に XCTest APIを使用する 検証を追加し アプリが期待どおりに 動作していることを確認します 最後に 他の自動化APIについて確認し テストをさらに強力なものにします

    記録されたUIクエリを確認し 調整が必要かどうか調べましょう 記録されたコードの各行には 各UI要素に 対処するための複数のオプションがあり どれを選択するかは目標によって異なります ソースコードの各行のドロップダウンを クリックすると選択肢が表示されます

    簡単に言うと 適切なものを選択すれば それだけ早くオーストラリア行きの 便に乗ることができます

    選択する際に役立つ いくつかの推奨事項があります

    テキスト要素やボタンなどローカライズ 対象の文字列を含むビューの場合は アクセシビリティ識別子があれば それを選択することをお勧めします UIの記録では 識別子が存在する場合 デフォルトでその識別子の使用を試みます

    スクロールビューのテキストのように 深くネストしたビューの場合は できるだけ短いクエリを 選択することをお勧めします これにより アプリの変更に応じて 自動化を容易に調整できます

    最後に インターネットから ダウンロードするコンテンツまたは タイムスタンプや温度など頻繁に変化する コンテンツなどの動的コンテンツの場合 より汎用的なクエリか 存在する場合はアクセシビリティ識別子を 使用することをお勧めします

    この例では識別子や文字列を使用しておらず 常に最初のテキストを参照しています

    では 選択を行ってみます 編集したいソースコードの行を クリックして オプションを表示します これらのクエリはどれも 操作した要素を一意に特定するため 不適切な選択肢はありません 今後のために このUIへの参照を どのように保存するかを 単に選択するだけです ここでは textFields.firstMatch オプションを選択し テスト内でテキストフィールドが その名称に関係なく 確実に参照されるようにします ドロップダウンをダブルクリックすると 結果がソースコードに保存されます では 自動化を簡単に再実行して 操作が正しく記録されているか 確認しましょう テストのひし形をクリックして実行します これはアプリをテストするものであり 忍耐力を試されることはありません 自動化の再生は非常に高速に実行されます

    コレクションが正しい名前ですぐに作成され 場所が追加され

    自動化がうまく機能しました 素晴らしいですね 19時間のフライトよりもずっと高速です 今度は コードに検証を追加して 想定した動作をするか確認します この例では グレートバリアリーフのランドマークが コレクションに追加されたことを確認します

    waitForExistenceなどの メソッドを呼び出して 自動化を待機させ 特定の要素が 表示されてから次に進ませます より汎用的なメソッド wait(for:toEqual:)を呼び出して XCUIElement上のプロパティが 想定した結果と一致することを 検証することもできます

    これら両方のメソッドをXCTestの XCTAssert文と組み合わせて これらのメソッドがfalseを返す場合に テストが失敗したと判断できます

    さて 私のコードに戻り コレクションの名前に対して waitForExistenceを追加し 以降の 実行時に常にそれを有効にしましょう

    次に コードをより強力にするために 他の自動化APIを確認しましょう

    XCTestCaseのsetUpインスタンス メソッドを使用すると 以降の実行時にデバイスを確実に 同じ状態にするのに役立ちます orientationやappearanceなどのAPIの 呼び出しや場所のシミュレートを行い 実行を開始する前にデバイスを 適切な状態にすることができます

    アプリを起動する前に launchArgumentsや launchEnvironmentなどの プロパティを使用して launchメソッドが呼び出されたときに これらのパラメータをアプリで使用できます

    アプリがカスタムURLスキームをサポート している場合 XCUIApplicationの openメソッドを直接使用して 一致する URLに対してアプリを開くことができます

    グローバルバージョンもあり デバイスのデフォルトアプリを 使用してURLを開きます

    最後に UIテスト内でアプリの アクセシビリティ監査を 実行できます 詳しくはWWDC23のセッション「Perform accessibility audits for your app」を ご覧ください インタラクションを記録し 自動化を設定したので デバイスとクラウドの両方において 複数の構成で再生するように テストを構成しましょう テストを新規または既存のテスト計画に 追加すると非常に便利です テスト計画では 個々のテストを 含めるか除外するかを決め テストを実行する場所や方法に関する システム設定を行い タイムアウト 繰り返し 並列化 実行順序などの テストプロパティを管理できます

    テスト計画をスキームに関連付けて テスト計画と特定のビルド設定を 組み合わせることもできます

    詳細については デベロッパ向けドキュメントの 「Improving code assessment by organizing tests into test plans」を ご覧ください

    テスト計画では 最初の画面でテストを 追加または削除できます また タブに切り替えて テストの実行方法を変更できます 複数の構成を設定して複数の言語で アプリを実行できます

    通常 各ロケールはテスト計画内の 独立した構成として存在します

    特定のロケール構成に焦点を 絞った設定を行ったり すべてのロケールで共有する その他の設定を行ったりできます

    ドイツ語のように長い文字列を 使用する言語や アラビア語やヘブライ語のように 右から左に書く言語のための 構成を含めると便利です

    タブには UI自動化に 関する設定もあります

    例えば 実行中にビデオや スクリーンショットをキャプチャするか 実行後にメディアを残すかなどがあります

    デフォルトでは 実行に失敗した場合のみ 問題を確認できるように ビデオとスクリーンショットを残します 実行に成功した場合もそれらを残すには を選択します この設定を使用すると ドキュメント チュートリアル マーケティングなど 他の目的のためにビデオ録画を 残すことができます タブには 他にも 多くの有用な設定があります 詳細については WWDC22の「Author fast and reliable tests for Xcode Cloud」をご覧ください

    Xcode CloudはXcodeに内蔵されたサービスで App Store Connectでも利用できます アプリのビルド テストの実行 App Store へのアップロードなど様々に役立ちます これらすべてがクラウドで行われ デベロッパやチームのデバイスを 使用する必要がありません Xcode Cloudなら すべて問題なく 実行できそうです Landmarksアプリ向けに Xcode Cloudワークフロー構成しました このワークフローは 私が作成したテスト計画を使用して 私が書いたすべてのUI自動化を実行します この計画は iPhoneとiPad上の英語 アラビア語 ヘブライ語 ドイツ語 など 任意の数のデバイスと構成で シミュレータで実行する場合と同様に クラウド内で実行されます

    Xcode Cloudの実行履歴はXcode内から またはApp Store Connectの セクションで確認できます そこでは ビルド情報の概要 ログ 失敗に関する説明などを確認できます

    Xcode Cloudを使用すると チームの 全員が私の実行履歴を確認でき 結果やビデオ録画をダウンロードできます 私が文字どおり雲の中にいても つまりシドニー行きの便に乗っていても チームはそのような作業を 行うことができます

    Xcode Cloudについて学ぶべきことは 他にもたくさんあります より高度な構成については WWDC23の「Create practical workflows in Xcode Cloud」をご覧ください 複数の構成でテスト計画を使用し 記録したテストを実行したので テストレポートを使用して 結果とビデオ録画を確認できます Xcodeのテストレポートには テスト結果の表示 理解 診断に役立つ 優れたツールがいくつかあります 実行したばかりの自動化で 複数の実行のうち1つが失敗したようです これではオーストラリアに行くための 荷物をまだ準備できません 失敗したテストに移動するために ボタンをクリックします 次に 失敗した実行をダブルクリックし ビデオ録画と何が起きたかの 説明を確認します

    このテストに含まれるすべての実行が 実行のドロップダウンに表示されます これにより 異なる言語など 様々な構成で実行したテストの ビデオ録画をすばやく切り替えることが できます また面白いことに 副ボタンのクリックに続いて を選択すると ビデオをダウンロードできます

    を押してビデオの再生を開始します

    ビデオを再生すると UIインタラクションを示すドットが ビデオの上に重ねて表示されます これらのアクションは 下部の タイムラインにもドットで示されます

    失敗までには少し時間がかかりそう ですのでスキップしましょう タイムライン上の失敗のひし形を使って 失敗の瞬間に直接ジャンプします

    失敗メッセージが表示されていますが 何が問題かを把握するのは難しいです メッセージは というボタンを 探していることを意味します 失敗の時点で実際に何が 起きていたかを見てみましょう

    失敗の時点で ビデオ録画の上に 存在していたすべてのUI要素の オーバーレイを確認できます

    いずれかの要素をクリックすると 自動化コード内でこの要素に対処するための 推奨コードが表示されます を押すと 別の例を表示して 最適なコードを見つけることができます 間違いがわかりました ここにボタンを表示する必要がありますが ボタンがありません ただのテキストです すぐに修正しましょう

    希望のサンプルコードを選択し 副ボタンのクリックを使ってコピーします

    次に をクリックして テストに直接移動し 新しいコード行を既存のコードに 貼り付けることができます

    一時的な変数XCUIApplicationを UI記録の変数appに置き換えると 準備は完了です

    これで想定どおりに動作するはずです テストのひし形をクリックして テストを再実行します 今回はアラビア語でテストを実行し 右から左に書くレイアウトで アプリが実行されているときでも 同じ自動化が機能することを確認します

    自動化により コレクションが すばやく作成され 英語と同じように名前が変更されます うまく機能します

    自動化が成功しました これを終わらせて 一生に一度の旅に出かけましょう 母と妹が案内してくれることでしょう Xcodeのテストレポートでは 他にも様々なことができます WWDC23のセッション「Fix failures faster with Xcode test reports」で 詳細を確認できます UIの自動化 アクセシビリティ ローカライズ Xcode Cloudおよびテストレポートを すべて連携させて アプリの品質を高め 世界中のすべての人にとって 使いやすくできるというのは 驚くべきことです これらの技術を 1つのフローに統合することは とても素晴らしいことであり 皆さんに使ってもらうのが待ち遠しいです

    単体テストとSwiftテストの詳細については WWDC24の「Meet Swift Testing」を ご覧ください ご質問やフィードバックがある場合は デベロッパフォーラムで 私たちにご連絡ください ありがとうございました オーストラリアでお会いしましょう

    • 7:52 - Adding accessibility identifiers in SwiftUI

      // Adding accessibility identifiers in SwiftUI
      import SwiftUI
      
      struct LandmarkDetailView: View {
        let landmark: Landmark
        var body: some View {
          VStack {
            Image(landmark.backgroundImageName)
              .accessibilityIdentifier("LandmarkImage-\(landmark.id)")
            
            Text(landmark.description)
              .accessibilityIdentifier("LandmarkDescription-\(landmark.id)")
          }
        }
      }
    • 8:19 - Adding accessibility identifiers in UIKit

      // Adding accessibility identifiers in UIKit
      import UIKit
      
      struct LandmarksListViewController: UIViewController {
        let landmarks: [Landmark] = [landmarkGreatBarrier, landmarkCairo]
      
        override func viewDidLoad() {
          super.viewDidLoad()
      
          for landmark in landmarks {
            let button = UIButton(type: .custom)
            setupButtonView()
                      
            button.accessibilityIdentifier = "LandmarkButton-\(landmark.id)"
            
            view.addSubview(button)
          }
        }
      }
    • 13:54 - Best practice: Prefer accessibility identifiers over localized strings

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().staticTexts["Max's Australian Adventure"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts["Collection-1"]
    • 14:09 - Best practice: Keep queries as concise as possible

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().scrollViews.staticTexts["Collection-1"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts["Collection-1"]
    • 14:21 - Best practice: Prefer generic queries for dynamic content

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().staticTexts["Max's Australian Adventure"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts.firstMatch
    • 15:49 - Add validations to a test case

      // Add validations to the test case
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testGreatBarrierAddedToFavorites() {
          let app = XCUIApplication()
          app.launch()
          app.cells["Landmark-186"].tap()
          XCTAssertTrue(
            app.staticTexts["Landmark-186"].waitForExistence(timeout: 10.0)),
            "Great Barrier exists"
          )
      
          let favoriteButton = app.buttons["Favorite"]
          favoriteButton.tap()
          XCTAssertTrue(
            favoriteButton.wait(for: \.value, toEqual: true, timeout: 10.0),
            "Great Barrier is a favorite"
          )
        }
      }
    • 16:36 - Set up your device for test execution

      // Set up your device for test execution
      import XCTest
      import CoreLocation
      
      class LandmarksUITests: XCTestCase {
      
        override func setUp() {
          continueAfterFailure = false
          
          XCUIDevice.shared.orientation = .portrait
          XCUIDevice.shared.appearance = .light
            
          let simulatedLocation = CLLocation(latitude: 28.3114, longitude: -81.5535)
          XCUIDevice.shared.location = XCUILocation(location: simulatedLocation)
        }
        
      }
    • 16:54 - Launch your app with environment variables and arguments

      // Launch your app with environment variables and arguments
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testLaunchWithDefaultCollection() {
          let app = XCUIApplication()
          app.launchArguments = ["ClearFavoritesOnLaunch"]
          app.launchEnvironment = ["DefaultCollectionName": "Australia 🐨 🐠"]
          app.launch()
      
          app.tabBars.buttons["Collections"].tap()
          XCTAssertTrue(app.buttons["Australia 🐨 🐠"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:04 - Launch your app using custom URL schemes

      // Launch your app using custom URL schemes
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testOpenGreatBarrier() {
          let app = XCUIApplication()
          let customURL = URL(string: "landmarks://great-barrier")!
          app.open(customURL)
      
          XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0))
          XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:12 - Launch your app using custom URL schemes and the system default app

      // Launch your app using custom URL schemes
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testOpenGreatBarrier() {
          let app = XCUIApplication()
          let customURL = URL(string: "landmarks://great-barrier")!
          XCUIDevice.shared.system.open(customURL)
      
          XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0))
          XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:13 - Perform an accessibility audit during an automation

      // Perform an accessibility audit during an automation
      import XCTest
      
      class LandmarksUITests: XCTestCase {
        
        func testPerformAccessibilityAudit() {
          let app = XCUIApplication()
          try app.performAccessibilityAudit()
        }
      
      }

Developer Footer

  • ビデオ
  • WWDC25
  • 記録、再生、レビュー:Xcodeを使用したUI自動化
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン