Espressoでダイアログが表示されるかどうかを確認します


87

新しいandroid-test-kit(Espresso)を使用していくつかのテストを作成しようとしています。しかし、ダイアログが表示されているかどうかを確認し、ダイアログに対していくつかのアクション(正ボタンと負ボタンをクリックするなど)を実行する方法についての情報が見つかりません。ダイアログはWebView、アプリケーション自体ではなく、によっても表示される場合があることに注意してください。

どんな助けでもいただければ幸いです。リンク、または基本的なサンプルコードが必要です。

  1. ダイアログが表示されるかどうかを確認します
  2. ダイアログボタンのクリックを実行します
  3. ダイアログの内部ビューを操作します(カスタムビューの場合)
  4. ダイアログの外側でプリフォームがクリックされ、表示されているかどうかを確認します(たとえばsetCancelable(false)、ダイアログビルダーで呼び出され、それを確認したい場合)。

アドバイスありがとうございます!


以下の私の答えに対するフィードバックはありますか?
2014年

回答:


125
  1. ダイアログが表示されるかどうかを確認するには、ダイアログ内にあるテキストを含むビューが表示されているかどうかを確認するだけです。

    onView(withText("dialogText")).check(matches(isDisplayed()));
    

    または、IDのテキストに基づく

    onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
    
  2. ダイアログボタンをクリックするには、これを行います(button1-OK、button2-キャンセル):

    onView(withId(android.R.id.button1)).perform(click());
    

    更新

  3. Espressoはマルチウィンドウをサポートしているので可能だと思います。
  4. カスタムダイアログビューの外側をクリックするかどうかはわかりませんが、表示されているかどうかを確認するには、カスタムマッチャーを作成して内側を確認する必要があります。

3
手順1は、ProgressDialogでは機能しませんでした。ダイアログのタイトルとメッセージを検証しようとしているだけ
Tim Boland 2014

1
エスプレッソと静的インポートとは何ですか?それらのメソッドはどのクラスから来ていますか?スタックオーバーフローの答えに静的インポートを使用しているのはなぜですか?

2
@jvrodriguesすべてのEspressoチュートリアルは静的インポートを使用します。私はあなたがそれに慣れることをお勧めします(私は欲求不満を理解していますが)。これは役立ちます:google.github.io/android-testing-support-library/docs
AutonomousApps

ステップ4では、ダイアログの外側をクリックする代わりに、「pressBack();」を呼び出すことができます。ダイアログを閉じます。これは、ハードウェアの戻るボタンを使用するのと同じです。
イーサン

@denysプロジェクトは移動されました。リンクが切れているようです。
ネオンウォージ2016年

67

私は現在これを使用していますが、問題なく動作しているようです。

onView(withText(R.string.my_title))
    .inRoot(isDialog()) // <---
    .check(matches(isDisplayed()));

28

そのようなAlertDialogがある場合:

ここに画像の説明を入力してください

コンポーネントが表示されているかどうかを確認できます。

int titleId = mActivityTestRule.getActivity().getResources()
        .getIdentifier( "alertTitle", "id", "android" );

onView(withId(titleId))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_title)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.text1))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_message)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button2))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.no)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button3))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.yes)))
        .check(matches(isDisplayed()));

アクションを実行します。

onView(withId(android.R.id.button3)).perform(click());

2
私の場合のテキストにはidがandroid.R.id.messageあり、タイトルには隠しIDがありましたandroid.R.id.alertTitle
ジェイソンロビンソン

2
あなたはAPPCOMPATサポートライブラリから来てAlertDialog(またはDialogFragment)を使用している場合は、これを使用する:int alertDialogTitleId = android.support.v7.appcompat.R.id.alertTitle;
MR-IDE

誰かがパラメータ値を知る必要がある場合は、stackoverflow.com / a / 15488321/1713366。名前やdefタイプがわからない場合check()は、存在しないビューを試して、logcatのレイアウト階層を確認してください。あなたはこれらの束を見るでしょうdefType = name。たとえばmessage=hello world、の場合、パラメータは次のようになります"hello world", "message", "your package name"
Jcorretjer

3

受け入れられた回答ではない質問4に回答するために、Toastが表示されたかどうかをテストするためにStack Overflow(リンク)で見つけた次のコードを変更しました。

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @IdRes int id) {
    return onView(withId(id)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

id渡されたがのIDでView、現在お使いのダイアログに表示します。次のようにメソッドを作成することもできます。

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @NonNull String text) {
    return onView(withText(text)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

そして今、それViewは特定のテキスト文字列を含むものを探しています。

そのようにそれを使用してください:

getRootView(getActivity(), R.id.text_id).perform(click());

3

ボタンIDR.id.button1とR.id.button2は、デバイス間で同じになることはありません。IDはOSのバージョンによって変わる可能性があります。

これを実現する正しい方法は、UIAutomatorを使用することです。build.gradleにUIAutomatorの依存関係を含めます

// Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

と使用

// Initialize UiDevice instance
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

// Search for correct button in the dialog.
UiObject button = uiDevice.findObject(new UiSelector().text("ButtonText"));
if (button.exists() && button.isEnabled()) {
    button.click();
}

1
実際にandroid.R.id.button1は、、android.R.id.button2およびandroid.R.id.button3「ポジティブ」、「ニュートラル」、「ネガティブ」は、使用できるグローバルシンボルです。テキストを介してボタンを選択することを選択した場合(これはまったく問題ありません)、UIAutomatorは必要ありませんが、Espressoでも同じことができますonView(withText("ButtonTest")).perform(click())
トーマス・ケラー

このソリューションをRobotiumテストフレームワークで使用したところ、AndroidOSのダイアログボックスのボタンを簡単に選択できました。たくさんの時間を節約できました。ありがとうjaydeepw!
レイ

@ThomasKeller過去にbutton1、button2 idを使用しましたが、さまざまなデバイスで実行するとテストが失敗しました。表示されるダイアログはシステムコントロールです。あなたのコントロール/ UIではありません。UI以外の場合は、UIAutomatorをお勧めします。
JaydeepW 2016

それでおしまい。大いに感謝する。
1lb3r

3

私のように誰かがこの質問に出くわした場合に備えて。すべての回答は、ダイアログボタンのあるダイアログでのみ機能します。ユーザーの操作なしに進行状況ダイアログにこれを使用しようとしないでください。Espressoは、アプリがアイドル状態になるのを待ち続けます。進行状況ダイアログが表示されている限り、アプリはアイドル状態ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.