1. 程式人生 > >UiAutomator2.0 - Toast資訊的驗證

UiAutomator2.0 - Toast資訊的驗證

目錄

問題:在做UI自動化測試時,偶爾會碰到 Toast 這種提示資訊(如圖),通過Uiautomatorviewer 無法獲該類控制元件的資訊。所以無法驗證,該條case不能實現。然後就沒然後了...

思考:在《UiAutomator2.0 - 與AccessibilityService的關聯》實驗後,發現Toast提示資訊所屬事件為                                   AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED

,依據《UiAutomator2.0 - 控制元件實現點選操作原理》中的分析,那也可以模仿原始碼監聽該事件啊!美滋滋~~

實現:準備著手實現時,發現其他類的相關方法並沒公開,只有UiAutomation這個類公開了setOnAccessibilityEventListener方法(通過該方法進行監聽Toast)。突破口找到了,那麼就從這個方法開始實現。


1、建立一個 VerifyToast類,程式碼如下:

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;
    }
}

2、測試用例中的呼叫

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 terminated

那麼在控制檯也直觀的檢視當前的Accessibility事件了,結果如圖: