Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test with Espresso a PendingIntent generated by TaskStackBuilder

I am developing some cool Push Notification in our app and making some test to cover that when the user clicks on one of the notification then the app launch the correct intent to open the correct Activity.

In our application we have a StartupActivity that captures all this push notifications and route to the correct screen with the correct extras. The UI test, done with Espresso, that cover the correct launch looks like this:

    @Test
    public void showsANotificationAndOpensTheCorrectScreen() throws
            UiObjectNotFoundException {
        sendBroadcast(PushNotificationBuilder
                .withAction("com.xxxx.android.gcm.SOMETHING")
                .withType("SOME_TYPE")
                .withRelatedId(ANY_ID)
                .withTitle(ANY_TITLE)
                .build());

        tapNotificationWithTitle(ANY_TITLE);

        intended(allOf(
                hasComponent(DesitinyActivity.class.getCanonicalName()),
                hasExtra("extra_id", Long.valueOf(ANY_ID)),
                hasExtra("extra_other_extra", true)));
    }

As you can see, this test simulates receive a notification, tap on it and checks if the Intent to the correct Activity is thrown.

The problem arrives when we have a screen that is not on the first level, for example the typical Detail Screen, and we need to build a stack of activities. For that we use TaskStackBuilderto generate a PendingIntent with all the stack of intents. An example code that generates the stack given a final Activity's intent:

private PendingIntent generateexampleTaskBuilder(Context context, Intent intentToTheFinalScreen) {
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addNextIntent(ExampleActivity.getLaunchIntent(someExtra, context));
        stackBuilder.addNextIntent(intent);
        return stackBuilder.getPendingIntent(PushIdIntegerGenerator.getUniquePushId(),
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

The problem is that the intended espresso method never verifies this Pending Intent and the test never pass. If I changed the pending intent for a normal and direct Intent the test passes. So we can assume that the method intended() can not captures the pending intents.

Is there any form to test the pending intents?

like image 931
Aracem Avatar asked Sep 27 '16 15:09

Aracem


1 Answers

Espresso Intents is a solution for hermetic testing. It lets you test with Espresso when you communicate with other apps via Intents.

Since you're staying within your app's boundaries, consider testing your UI by verifying that the correct screen is displayed in each navigation step. How you go from screen to screen is an implementation detail. Tap notification > verify title is shown > press back > verify list is shown.

like image 154
Jose Alcérreca Avatar answered Oct 23 '22 11:10

Jose Alcérreca