UiAutomator2.0 - 獲取同行控件

目錄android

問題:UI測試時,在同一個界面出現相同的屬性的控件(如圖),對於這種控件的獲取非常無奈。若是直接經過控件id去查找的話老是會返回界面該類型的第一個控件。
測試

解決
1.UiObject2 中已經給出瞭解決方法,能夠經過 getParent()方法處理。缺點:因爲UiObjec2t控件與視圖進行綁定,當視圖變化後該控件對象就被銷燬了。因此屢次使用則很是不便利ui

@Test
public void testCase_Btn(){
       UiObject2 switchBtn = device.findObject(By.text("Automatic 24‑hour format"))
               .getParent().getParent().findObject(By.res("android:id/switch_widget"));
       if(switchBtn.isChecked()){
           switchBtn.click();
       }
       assertTrue("switch btn is open", !switchBtn.isChecked());
}

2.UiObject中經過id + instance 去能查找到控件,可是界面變更的話腳本也得變更,可靠性不強。只能採起折中的方式來獲取了。很少說,直接上代碼。code

UiObject switchBnt3 = device.findObject(new UiSelector().resourceId("android:id/switch_widget").instance(2));orm

測試類:對象

@Test
public void testCase_Btn() throws UiObjectNotFoundException {
       UiObject timeFormat = device.findObject(new UiSelector().text("Automatic 24‑hour format"));
       UiObject switchBtn = ControlObj.getUiObject(timeFormat);
       if(switchBtn.isChecked()){
           switchBtn.click();
       }
       assertTrue("switch btn is open", !switchBtn.isChecked());
}

幫助類:blog

package com.zzw.commonutils.commons;

import android.graphics.Rect;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiCollection;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.util.Log;

/**
 * @author zzw
 */
public class ControlObj {
    private static final String TAG = ControlObj.class.getSimpleName();


    public static UiObject getUiObject(UiObject obj) throws UiObjectNotFoundException {
        UiCollection list = new UiCollection(new UiSelector().resourceId("com.android.settings:id/list"));
        UiObject switchBtn = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
                .findObject(new UiSelector().resourceId("android:id/switch_widget"));
        return getUiObject(list, obj,switchBtn );
    }

    /**
     * 獲取同行的控件
     * @param uic UiCollection
     * @param uio The same row UiObject as the target UiObject
     * @param uio2 Target UiObject
     * @return An UiObject
     * @throws UiObjectNotFoundException maybe can't find UiObject
     */
    public static UiObject getUiObject(UiCollection uic, UiObject uio, UiObject uio2) throws UiObjectNotFoundException {
        UiObject obj = null;
        UiSelector uis = uio2.getSelector();
        Log.i(TAG, "getUiObject: "+  uic.getChildCount(uis));
        for(int i=0; i< uic.getChildCount(uis); i++){
            UiObject uiObject = uic.getChildByInstance(uis, i);
            boolean result = isSameLine(uio, uiObject);
            Log.i(TAG, "getUiObject: "+result );
            if(result){
                obj = uiObject;
                break;
            }
        }
        if(obj == null){ throw new RuntimeException("Get "+ uio.getSelector()+" same line UiObject error");}
        return obj;
    }

    /**
     * 判斷兩個控件是否在同一行
     * @param obj1 UiObject 1
     * @param obj2 UiObject 2
     * @return return true, if is same line
     * @throws UiObjectNotFoundException maybe can't find UiObject
     */
    private static boolean isSameLine(UiObject obj1, UiObject obj2) throws UiObjectNotFoundException {
        Rect first = obj1.getBounds();
        Rect second = obj2.getBounds();
        Log.i(TAG, "isSameLine: f:"+ first + ", s"+second);
        // 比較區域
        return first.top< second.bottom && first.bottom > second.top ;
    }
}
相關文章
相關標籤/搜索