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

アールケー開発 | macOS/iOSアプリ・SDK・ミドルウェア開発の専門家・開発者 - にほんブログ村

アイキャッチ画像は 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++使い。豊富な開発実務経験を基に、教育コンテンツ開発、技術書執筆、技術指導、技術セミナー講師、企業内研修講師、行政・自治体職員研修講師も行います。

関連記事

  1. WKWebViewでBasic認証を行う

  2. 【2020/2/10更新】UIWebViewは廃止

  3. WKWebViewとSFSafariViewControllerのどち…

  4. コマンドライン引数でモックに差し替える

  5. 【2020/4/1更新】【Swift|ObjC 】 UIWebView…

  6. iOS 13.4でWKWebViewがクラッシュするときはWebKit…

最近の著書

  1. 基礎から学ぶ SwiftUI

最近の記事

  1. 2020.10.21

    GitLabへの移行
PVアクセスランキング にほんブログ村