简体   繁体   中英

Android - automated test for receiving GCM push notifications

How to add test coverage for receiving a GCM notification? Test scenario: my app in background, notification arrives, check that it's displayed, click notification to open app. It works in emulator when I test manually. I got bit by Android Notification Not Showing On API 26 so need a test to detect breakages. I saw this How to detect headsup notification in uiautomator? but it doesn't show how to create a notification for my app.

UPDATE I figured out how to create an intent that is handled by the receiver.

    // app already started and in background
    Intent intent = new Intent();
    intent.setAction("com.google.android.c2dm.intent.RECEIVE");
    intent.putExtra("from", "1234567890");
    intent.putExtra("message", "Android may be hard, but iOS is even harder");
    Context context = InstrumentationRegistry.getInstrumentation().getContext();
    context.sendBroadcast(intent); 

My receiver and listener:

    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!--category tag not required if min SDK 16 or higher-->
        </intent-filter>
    </receiver>

    <service
        android:name=".gcm.MyGcmListenerService"
        android:permission="com.google.android.c2dm.permission.RECEIVE"
        android:exported="true" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

The solution involved figuring out a few things.

  1. In AndroidManifest.xml, for receiver element the category tag is ignored for SDK 16 and up.
  2. The notification displayed can vary based on if app is in foreground or background.
  3. The UISelector to find notifications had different className than in the example at link above. Start by using just "textContains" method, then refine your selector.
  4. Our GcmListenerService was ignoring messages that didn't have the from specified, so had to add "from" to my intent.
  5. I couldn't find a way to view existing GCM messages on https://console.firebase.google.com , so it was trial and error to get my Intent to match what server sends (eg, from field is not explicitly set by server app)

Checking if notification is displayed is tricky because notification drawer can't be inspected using Android Studio Layout Inspector. So it's trial and error to find the elements. I did this:

    UiSelector textSelector = new UiSelector().textContains("some text in my message");
    UiObject notificationText = device.findObject(textSelector);

Then output the attributes of the UiObjects so I could make selector more specific (adding packageName and className).

Code for my test intent and receiver/service elements is in the question's UPDATE section.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM