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