MacアプリのUIテスト – ダイアログのテスト

アイキャッチ画像は acworksさんによる写真ACからの写真 を利用しています。

MacアプリのUIテストで、ダイアログのテスト方法についてです。

ダイアログの表示待機

何かボタンをクリックしたら表示されるダイアログ、アプリ起動時に表示されるダイアログ、メニューからコマンドを実行すると表示されるダイアログなど、色々な方法でダイアログは表示されます。しかし、どの方法であっても共通するのは、表示されるまで待機するということです。

マシンスペックやマシンの状態などによって、どのくらいのタイミングでダイアログが表示できるかというのは微妙に異なります。それらに依存せずにダイアログが表示されるまで待機すると同時にダイアログが表示されることをテストするには、次のようにします。

let app = XCUIApplication()

// "alert_window"という識別子のダイアログの表示待機
let alertDialog = app.dialogs["alert_window"]
XCTAssertTrue(alertDialog.waitForExistence(timeout: 5))

タイムアウトの5秒は、そこまでかかることはないという値です。

“dialogs”と”windows”のどちらを使うか

XCTestでウインドウを取得するときに、「dialogs」を使うか「windows」を使うかは、取得対象のウインドウのイベント処理の方法で決まります。

次のようにモーダルダイアログとして使っているときは「dialogs」です。ドキュメントウインドウなど、ウインドウを表示しているだけで、モーダルセッションを使っていないときは「windows」です。

NSApplication.shared.runModal(for: alert.window!) 

共通ダイアログクラスが連続するとき

共通のダイアログクラス、例えば、アラートメッセージ用のクラスなど、識別子が同じダイアログが連続して表示されるみたいなときには、スリープを入れると判定できます。

次のコードは、最初のアラートで「削除しても良いですか?」と確認しています。「OK」ボタンがクリックされたら、「ロックされている項目があります。強制的に削除しますか?」と表示されるかをテストしているコードです。文字列はLocalizable.stringsから取得しています。

let app = XCUIApplication()
var bundle = Bundle(for: type(of: self))

XCTContext.runActivity(named: "1st alert") { (activity) -> Void in
    // "alert_window"という識別子のダイアログの表示待機
    let alertDialog = app.dialogs["alert_window"]
    XCTAssertTrue(alertDialog.waitForExistence(timeout: 5))

    // "message_label"の取得と存在チェック
    let label = alertDialog.staticTexts["message_label"]
    XCTAssertTrue(label.exists)

    // メッセージの表示内容をチェック
    XCTAssertEqual(label.value as? String,
        bundle.localizedString(forKey: "ConfirmDelete", value: nil, table: nil))

    // OKボタンの取得と存在チェック
    let okButton = alertDialog.buttons["ok_button"]
    XCTAssertTrue(okButton.exists)

    // OKボタンをクリック
    okButton.click()
}

// アラートが閉じて、別のアラートが表示されるので、1秒待つ
Thread.sleep(forTimeInterval: 1)

XCTContext.runActivity(named: "2nd alert") { (activity) -> Void in
    // "alert_window"という識別子のダイアログの表示待機
    let alertDialog = app.dialogs["alert_window"]
    XCTAssertTrue(alertDialog.waitForExistence(timeout: 5))

    // "message_label"の取得と存在チェック
    let label = alertDialog.staticTexts["message_label"]
    XCTAssertTrue(label.exists)

    // メッセージの表示内容をチェック
    XCTAssertEqual(label.value as? String,
        bundle.localizedString(forKey: "ItemIsLocked_ConfirmDeleteForce", value: nil, table: nil))

    // OKボタンの取得と存在チェック
    let okButton = alertDialog.buttons["ok_button"]
    XCTAssertTrue(okButton.exists)

    // OKボタンをクリック
    okButton.click()
}

投稿者プロフィール

林 晃
林 晃アプリ開発者
アールケー開発代表。Appleプラットフォーム向けのアプリ開発が好きなアプリ開発者。アプリの受託開発、技術書執筆、技術指導・セミナー講師。3DCGコンテンツ作成にも取組中です。

基礎から学ぶARKit


「基礎から学ぶARKit」を執筆しました。本書はARKitを使ったARアプリの開発方法を解説した技術書です。

ARKitを使ってARアプリを作るときの流れや基本的なAPIの使い方などをサンプルアプリを作りながら学べます。

詳細

基礎から学ぶMetal


「基礎から学ぶMetal」を執筆しました。本書はMetalを使ってGPUプログラミングを行うための最初のステップを解説するMetalの解説書です。

私が初めてGPUプログラミングを行ったとき、どこから手をつけて、学んでいけば良いのか分からず呆然としました。もし、あのとき、これを教えてくれればという部分を解説しました。本書で解説している部分はMetalの基礎となる部分で、Metalを使うときに必ず触れることになる部分です。

詳細

関連記事

  1. Apple Notarization Service に対応するための…

  2. macOSでDockerを使うときはプライバシー設定も確認する

  3. iOS アプリの開発に必要な Apple ID の作り方

  4. macOS Big Sur 11以降でドライバ(KEXT)の許可を取り…

  5. OpenCVのセットアップ方法(iOSアプリ用)

  6. Objective-CのコードをSwiftに対応してブラッシュアップさ…

最近の著書

  1. 基礎から学ぶ SwiftUI

最近の記事