web-dev-qa-db-ja.com

Espressoで実際にアクティビティを開始せずに送信された予想インテントを確認するにはどうすればよいですか?

ボタンをクリックしてから、onClickListenerで新しいアクティビティを起動するUIテストがあります。テストでは、期待されるインテントが送信されているかどうかを確認します。

私の問題は、実際にアクティビティを起動せずに期待されるインテントが送信されるかどうかをテストしたいということです。新しいアクティビティがその状態を初期化し、後続のテストが不安定になることがわかったためです。

intendedintendingの2つの Espresso Intents apiがあることは知っていますが、どちらも私のニーズを満たしていません。 intended apiは実際にターゲットアクティビティを起動し、intending apiはアクティビティを起動しませんが、onActivityResultコールバックを呼び出します。これも必要ありません。 onActivityResult内のコードが、別の不安定さを引き起こす可能性があるためです。また、intendingは、一致するインテントが送信されたかどうかを表明せず、一致するインテントが見つかったときにonActivityResultコールバックを呼び出すだけです。つまり、onActivityResultが呼び出されたかどうかを確認する必要があります。 !!

私が望むことを達成するためのクリーンな方法はありますか?

11
김준호

EspressoのIntentsクラスは簡潔で便利なAPIですが、ニーズに合わない場合は別の方法があります。 _AndroidJUnit4_テストランナーを使用する場合は、InstrumentationRegistry.getInstrumentation()を使用して_Instrumentaion_インスタンスを取得してから、_Instrumentation.ActivityMonitor_インスタンスを追加できます。

_Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor("YOUR_ACTIVITY", null, true);
InstrumentationRegistry.getInstrumentation().addMonitor(am);
onView(withId(R.id.view_id_to_perform_clicking)).check(matches(isDisplayed())).perform(click());
assertTrue(InstrumentationRegistry.getInstrumentation().checkMonitorHit(am, 1));
_

ActivityMonitorコンストラクターの3番目のパラメーターは、アクティビティの起動をブロックすることを指示します。このアプローチには制限があることに注意してください。 Espresso Intents ' リッチマッチャーサポート とは対照的に、ActivityMonitorに複数の条件を設定することはできません。

ApiDemos 、特に_ContactsSelectInstrumentation_クラスにいくつかのサンプルがあります。

3
김준호

実際にアクティビティを起動せずに期待されるインテントが送信されるかどうかをテストする場合は、activityResultでインテントをキャプチャしてから、アクティビティをキャッチすることでテストできます。

Intent intent = new Intent();
ActivityResult intentResult = new ActivityResult(Activity.RESULT_OK,intent);

intending(anyIntent()).respondWith(intentResult);

onView(withId(R.id.view_id_to_perform_clicking)).check(matches(isDisplayed())).perform(click());

intended(allOf(hasComponent(ActivityToBeOpened.class.getName())));

これにより、ActivityToBeOpenedを起動しようとする試みがすべてキャッチされます。より具体的にしたい場合は、Extrasでインテントをキャッチすることもできます。

intended(allOf(hasComponent(ActivityToBeOpened.class.getName()), hasExtra("paramName", "value")));

お役に立てば幸いです。

12
FOMDeveloper

実際には、外部または独自のアクティビティを起動するインテントをブロックできますが、それでも豊富なEspresso IntentsAPIを使用できます。

    Instrumentation.ActivityMonitor soloMonitor = solo.getActivityMonitor();
    instrumentation.removeMonitor(soloMonitor);
    IntentFilter filter = null;
    // Block any intent
    Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(filter, null, true);
    instrumentation.addMonitor(soloMonitor);

    // User action that results in an external browser activity being launched.
    user.clickOnView(system.getView(R.id.callButton));
    instrumentation.waitForIdleSync();

    Intents.intended(Matchers.allOf(
            IntentMatchers.hasAction(Matchers.equalTo(Intent.ACTION_VIEW)),
            IntentMatchers.hasData(Matchers.equalTo(Uri.parse(url))),
            IntentMatchers.toPackage(chromePackage)));

    instrumentation.removeMonitor(monitor);

Espresso Intentsは、ブロックしてもすべてのIntentを IntentMonitor コールバックで記録するため、これを行うことができます。 Espresso Intents のソースコードを見てください。

Robotium Solo フレームワークを使用する場合は、独自のActivityMonitorをフレームワークの前に移動する必要があります。それ以外の場合は、これに関連する行をスキップしてください。

1
Bogdan Kornev