[TOC]html
問題:在作UI自動化測試時,偶爾會碰到 Toast 這種提示信息(如圖),經過Uiautomatorviewer 沒法獲該類控件的信息。因此沒法驗證,該條case不能實現。而後就沒而後了... android
思考:在《UiAutomator2.0 - 與AccessibilityService的關聯》實驗後,發現Toast提示信息所屬事件爲 AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED
,依據《UiAutomator2.0 - 控件實現點擊操做原理》中的分析,那也能夠模仿源碼監聽該事件啊!美滋滋~~shell
實現:準備着手實現時,發現其餘類的相關方法並沒公開,只有UiAutomation這個類公開了setOnAccessibilityEventListener方法(經過該方法進行監聽Toast)。突破口找到了,那麼就從這個方法開始實現。
一、建立一個 VerifyToast類,代碼以下:app
package com.testtoast; import android.app.Notification; import android.app.UiAutomation; import android.os.Parcelable; import android.support.test.InstrumentationRegistry; import android.util.Log; import android.view.accessibility.AccessibilityEvent; /** * @author zzw * Toast Validation Helper */ public class VerifyToast { private static final String TAG = TestCase_FM.class.getSimpleName(); private static VerifyToast verifyToast = new VerifyToast(); private boolean isPass; private VerifyToast(){} public static VerifyToast getVerifyToast(){ return verifyToast; } public boolean getIsPass(){ return isPass; } public VerifyToast setIsPass(boolean isPass){ this.isPass = isPass; return this; } /** * Listen for toast prompts * @param pck The package name of toast * @param msg Toast info */ public void monitoringToast(final String pck, final String msg){ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); uiAutomation.setOnAccessibilityEventListener(new UiAutomation.OnAccessibilityEventListener() { @Override public void onAccessibilityEvent(AccessibilityEvent event) { if(event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED){ Log.d(TAG, "onAccessibilityEvent:"+ String.format("--pck: %s --msg: %s",getPackage(event),getMessage(event))); isPass = pck.equals(getPackage(event)) && msg.equals(getMessage(event)); Log.d(TAG, "onAccessibilityEvent: isPass = "+ isPass); } } }); } // 獲取監聽的包名 private String getPackage(AccessibilityEvent event){ return (String) event.getPackageName(); } // 獲取 Toast 信息 private String getMessage(AccessibilityEvent event){ String message = null; Parcelable parcelable = event.getParcelableData(); if (!(parcelable instanceof Notification)) { message = (String) event.getText().get(0); } return message; } }
二、測試用例中的調用ide
package com.testtoast; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiSelector; import android.util.Log; import com.zzw.commonutils.UiApps; import com.zzw.tools.ScreenCap; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; import static junit.framework.Assert.assertTrue; /** * @author zzw * Test for Toast */ @RunWith(AndroidJUnit4.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestCase_FM { private static final String TAG = TestCase_FM.class.getSimpleName(); private UiDevice device= UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); private String catchFail = "Catch_Pic"; @BeforeClass public static void before(){ Log.d(TAG, "before: -----------------------------start-------------"); } @Test public void testCase_GetToast() throws Throwable { VerifyToast verifyToast = VerifyToast.getVerifyToast(); String pck = "com.caf.fmradio"; String msg = "Please plug in a Headset to use FM Radio"; device.pressHome(); UiObject app= device.findObject(new UiSelector().text("FM Radio")); Log.d(TAG, "testCase_GetToast: result == "+verifyToast.getIsPass()); verifyToast.setIsPass(false).monitoringToast(pck,msg); try{ new UiApps().toOpenApp(app); //本身封裝打開app的方法 assertTrue("Toast prompt error", verifyToast.getIsPass()); }catch (Throwable e){ e.printStackTrace(); // 本身封裝的截圖方法 ScreenCap.takeScreenshotToPicturesDirPath(catchFail); throw e; } Log.d(TAG, "testCase_GetToast: result == "+verifyToast.getIsPass()); } }
注:在 adb shell uiautomator --help
中有這麼一句測試
events: prints out accessibility events until terminatedui
那麼在控制檯也直觀的查看當前的Accessibility事件了,結果如圖: this