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. 仮想環境と古いXcodeそして古いOS

  2. Notarization Service の条件の緩和終了

  3. OpenCVのセットアップ方法 (macOSアプリ用)

  4. XcodeでGoogle Test (gtest) を使えるようにセッ…

  5. Xcode 10対応 : 古いヘッダーマップはサポートされなくなる

  6. XcodeやAppCodeで16進数や2進数で値を確認する方法

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

  8. Xcode 8.3に移行したらnullabilityのワーニングが出た…

最近の著書

  1. 基礎から学ぶ SwiftUI

最近の記事