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()
}

投稿者プロフィール

林 晃
林 晃macOS/iOSアプリ/SDK/ミドルウェア開発が専門の開発者
アールケー開発代表。macOS/iOSアプリ/SDK/ミドルウェア開発が専門の開発者。ObjC/Swift/C++使い。豊富な開発実務経験を基に、教育コンテンツ開発、技術書執筆、技術指導、技術セミナー講師、企業内研修講師、行政・自治体職員研修講師も行います。

基礎から学ぶMetal


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

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

詳細

基礎から学ぶSwiftUI


「基礎から学ぶ SwiftUI」というタイトルの本を執筆しました。

SwiftUIの入門書です。

SwiftUIのコンセプトは「ユーザーインターフェイスを作るための最短パスを提供する」「一度学べば(Appleのプラットフォームの)どこにでも適用できる」です。

SwiftUIの概要から始まって、一つ一つのテクノロジートピックに注目しながらSwiftUIとは何か?どんなことができるのか?どのようなコードを書けば良いのかなどを丸々一冊使って解説しています。

詳細

関連記事

  1. SwiftのUnsafeMutableBufferは[]演算子よりも速…

  2. OpenCVで使われている並列化を見てみる

  3. M1 Mac への JDK のセットアップ

  4. SwiftからC言語の関数を使う

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

  6. HTTPのステータスコードへの対応

最近の著書

  1. 基礎から学ぶ SwiftUI

人気記事

最近の記事